如何知道在使用SupportMapFragment时地图已准备好使用?

onCreate方法中,我正在使用SupportMapFragment来显示地图。

  SupportMapFragment fragment = new SupportMapFragment(); getSupportFragmentManager().beginTransaction() .add(android.R.id.content, fragment).commit(); 

结合这一点,我想添加一个标记。 问题是什么时候getMap的调用是空的,什么时候可以再试一次? 有没有我可以注册的事件,或者我的方法本身是错误的?

  mMap = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap(); if(mMap == null) //what do I do here? 

地图实际上显示在手机上,但是我似乎没有运气来获得添加标记的参考。

更新:

我通过构造函数创buildSupportMapFragment的原因是典型的setContentView崩溃,无法正常工作。 这使我陷入了困境,因为我当时实际上正在创buildSupportMapFragment ,所以无法在onCreate方法中获得我的引用。 在进一步调查中,似乎我的setContentView问题是没有将Google-play-services jar和module / src设置为整个项目的一部分的副产品。 在做这两个, setContentView现在的作品,我可以通过getMap() ,我所期望的参考。

lots.xml …

 <?xml version="1.0" encoding="utf-8"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> 

LotsActivity.java …

 public class LotsActivity extends FragmentActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.lots); GoogleMap mMap; mMap = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap(); if(mMap == null) //this should not occur now } 

编辑: getMap现在已经被弃用了

问题是什么时候getMap的调用是空的,什么时候可以再试一次?

这取决于问题的性质。

如果通过布局中的<fragment>元素设置SupportMapFragment ,则可以在onCreate()成功调用getMap() onCreate() 。 但是,如果通过构造函数创buildSupportMapFragment ,那就太快了 – GoogleMap还不存在。 您可以扩展SupportMapFragment并覆盖onActivityCreated() ,因为getMap()已经准备好了。

但是, getMap()可以返回null来解决更大的问题,例如未安装Google Play服务。 您需要使用类似GooglePlayServicesUtil.isGooglePlayServicesAvailable()来检测这种情况,然后根据需要进行处理。

我最终扩展了SupportMapFragment类并使用callback。 代码在这里:

 public class MySupportMapFragment extends SupportMapFragment { public MapViewCreatedListener itsMapViewCreatedListener; // Callback for results public abstract static class MapViewCreatedListener { public abstract void onMapCreated(); } @Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); // Notify the view has been created if( itsMapViewCreatedListener != null ) { itsMapViewCreatedListener.onMapCreated(); } return view; } } 

我宁愿使用接口并重写onAttach(activity)方法,但在我的情况下,我不希望callback回到我的MainActivity。 我希望它能够返回到Fragment的一个实例。 (谷歌地图本质上是一个片段内的片段)我设置callback,并以此编程加载地图。 我想在MySupportMapFragment的构造函数中设置它的MapViewCreatedListener,但不鼓励使用除无参数构造函数以外的任何东西。

 itsMySupportMapFragment = new MySupportMapFragment(); MapViewCreatedListener mapViewCreatedListener = new MapViewCreatedListener() { @Override public void onMapCreated() { initPlacesGoogleMapCtrl(); } }; itsMySupportMapFragment.itsMapViewCreatedListener = mapViewCreatedListener; FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.mapFragmentContainer, itsMySupportMapFragment); transaction.addToBackStack(null); transaction.commit(); 

然后,当我接到电话,我可以得到地图; 没有更多的空!

 public void initPlacesGoogleMapCtrl() { // Map ready, get it. GoogleMap googleMap = itsMySupportMapFragment.getMap(); // Do what you want... } 

我会评论CommonsWare的答案,但我没有足够的代表。 无论如何,我也有这个问题getMap()将在onActivityCreated返回null。 我的设置是这样的:我有MainActivity包含一个片段。 在该片段的onCreateView方法中,我创build了SupportMapFragment,然后通过childFragmentManager将其添加到片段。 我一直参考SupportMapFragment,并期望它给我onActivityCreated它没有的地图。 解决这个问题的方法是覆盖SupportMapFragment的onActivityCreated而不是父代片段。 我在onCreateView中这样做了:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_location, container, false); mMapFragment = new SupportMapFragment() { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mMap = mMapFragment.getMap(); if (mMap != null) { setupMap(); } } }; getChildFragmentManager().beginTransaction().add(R.id.framelayout_location_container, mMapFragment).commit(); return v; } 

上个月(2014年12月)Google正式解决了这个问题。 最新(6.5)Google Play服务 :

MapView和MapFragment中的getMap()方法现在已被弃用,以支持新的getMapAsync()方法。

使用getMapAsync(OnMapReadyCallback callback)您可以在GoogleMap准备就绪时设置侦听器。 它在callback中被传递,并且被提供为非空。

Google为此提供了示例代码 :

 public class MainActivity extends FragmentActivity implements OnMapReadyCallback { ... } 

和初始化片段时:

 MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this); 

当地图准备就绪时,你将会调用callback函数

 @Override public void onMapReady(GoogleMap map) { map.addMarker(new MarkerOptions() .position(new LatLng(0, 0)) .title("Marker")); } 

你也可以使用MapsInitializer.initialize(context); 如果问题与未初始化的库有关。

使用最新的GoogleServices,您可以使用MapFragment.getMapAsync 。 直接从文档

设置一个callback对象,当准备使用GoogleMap实例时将会触发该对象。

如果map == null,那么find地​​图

  if (mGoogleMap == null) { SupportMapFragment mapFragment1 = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mapFragment1.getMapAsync(this); } 

然后在MapReady()上调用你的函数。