自定义片段(NPE)内的Android Maps V2 MapView

dnk*_*tso 22 maps android google-maps

我不想使用或扩展SupportMapFragmentMapFragment.我有自己的基类,里面有一堆代码.

文档清楚地指出,当有人单独使用时MapView,onCreate() onResume()应调用所有相应的生命周期方法(等).

a中的大多数生命周期方法Fragment都类似于a,Activity但是当我在我之间来回切换时,我Fragment最终会onDestroy()onResume()方法中或方法中获得混淆的NPE .

所有样品提供使用ActivityMapView,但不是自定义Fragment.

有人做过吗?你能提供MapView自己Fragment班级的样本代码吗?

Jen*_*ohl 35

我在PoPy的回答中苦苦挣扎,但最终我设法了,这就是我想出来的.可能这对其他人也有帮助,这些人也会遇到这个问题:

public class MyMapFragment extends Fragment {

    private MapView mMapView;
    private GoogleMap mMap;
    private Bundle mBundle;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View inflatedView = inflater.inflate(R.layout.map_fragment, container, false);

        try {
            MapsInitializer.initialize(getActivity());
        } catch (GooglePlayServicesNotAvailableException e) {
            // TODO handle this situation
        }

        mMapView = (MapView) inflatedView.findViewById(R.id.map);
        mMapView.onCreate(mBundle);
        setUpMapIfNeeded(inflatedView);

        return inflatedView;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBundle = savedInstanceState;
    }

    private void setUpMapIfNeeded(View inflatedView) {
        if (mMap == null) {
            mMap = ((MapView) inflatedView.findViewById(R.id.map)).getMap();
            if (mMap != null) {
                setUpMap();
            }
        }
    }

    private void setUpMap() {
        mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
    }

    @Override
    public void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        mMapView.onDestroy();
        super.onDestroy();
    }
}
Run Code Online (Sandbox Code Playgroud)

这里是相应的res/layout/map_fragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.google.android.gms.maps.MapView
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

如果在布局中只有一个元素(如本示例中所示),则可以省略RelativeLayout(并将xmlns声明移动到新的根元素,在本例中为com.google.android.gms.maps.MapView).

  • 谢谢你的实施.我注意到了一个问题.从backstack恢复此地图片段时,地图相机位置将丢失.在我当前的实现中,我每次在片段实例变量中更改时都使用OnCameraChangeListener来保存相机位置.从backstack恢复片段时,我检查此实例变量,如果它不为null,则将地图相机移动到此保存位置. (2认同)

小智 13

我成功地将MapView(v2)包含在ViewPager中嵌入的自定义Fragment中.在我的例子中,MapView包含在Fragment布局文件中.我不得不呼吁MapView类(生命周期方法onCreate()称为onCreateView()从片段),并手动调用MapsInitializer.initialize(context),以避免NullPointerException从类BitmapDescriptorFactory(以获取标记位图).最后一招很奇怪,我不知道为什么没有这个调用就没有正确地初始化Map系统,也许这只是当前版本中的一个bug ...

在我的情况下,我没有任何NullPointerExceptionin onResume()onDestroy().