30

在该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?

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

更新:

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

很多.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" />

很多活动.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
    }
4

7 回答 7

35

编辑:getMap现在已弃用

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

这取决于问题的性质。

如果在布局中设置了SupportMapFragmentvia元素,就可以在. 但是,如果您通过构造函数创建 ,那还为时过早——尚不存在。您可以扩展和覆盖,因为那时已经准备好了。<fragment>getMap()onCreate()SupportMapFragmentGoogleMapSupportMapFragmentonActivityCreated()getMap()

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

于 2012-12-26T23:01:54.443 回答
14

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

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) 方法,但就我而言,我不希望回调返回到我的 MainActivity。我希望它返回到 Fragment 的一个实例。(GoogleMap 本质上是一个片段中的一个片段)我设置了回调并用它以编程方式加载了地图。我想在 MySupportMapFragment 的构造函数中设置 itsMapViewCreatedListener,但不鼓励使用除无参数构造函数以外的任何东西。

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...
}
于 2013-03-08T21:15:39.263 回答
11

我会评论 CommonsWare 的答案,但我没有足够的代表。无论如何,我也遇到了 getMap() 会在 onActivityCreated 中返回 null 的问题。我的设置是这样的:我的 MainActivity 包含一个片段。在该片段的 onCreateView 方法中,我创建了 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;   
}
于 2013-02-19T11:56:33.403 回答
7

上个月(2014 年 12 月)谷歌给出了这个问题的官方解决方案。在最新的 (6.5) Google Play 服务中:

MapView 和 MapFragment 中的 getMap() 方法现已弃用,取而代之的是新的 getMapAsync() 方法。

getMapAsync(OnMapReadyCallback callback)您可以为 GoogleMap 准备就绪时设置监听器。它在回调中传递,并提供为非空值。

谷歌为此提供了示例代码

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

并在初始化片段时:

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

当地图准备好时,您的回调将被调用

@Override
public void onMapReady(GoogleMap map) {
    map.addMarker(new MarkerOptions()
        .position(new LatLng(0, 0))
        .title("Marker"));
}
于 2015-01-03T01:12:57.060 回答
0

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

于 2013-01-02T22:38:39.183 回答
0

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

设置一个回调对象,该对象将在 GoogleMap 实例准备好使用时触发。

于 2014-12-31T16:44:15.393 回答
0

如果 map == null 然后找到地图

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

        mapFragment1.getMapAsync(this);
    }

然后调用你的函数 onMapReady();

于 2016-09-30T12:56:57.797 回答