【问题标题】:SupportMapFragment's getMap() returns nullSupportMapFragment 的 getMap() 返回 null
【发布时间】:2013-05-01 16:17:57
【问题描述】:

我正在尝试动态创建 SupportMapFragment 并将其放入 FrameLayout 容器中。

我的问题是 mMapFragment.getMap() 返回 null...

有人可以帮忙吗?

CenterMapFragment.java

public class CenterMapFragment extends Fragment {

    private SupportMapFragment mMapFragment;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        return inflater.inflate(R.layout.center_map_fragment, container, false);
    }

    @Override
    public void onActivityCreated (Bundle savedInstanceState){
        super.onActivityCreated(savedInstanceState);

        if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity()) == ConnectionResult.SUCCESS) {
            setUpMapIfNeeded();
        }
    }


    private void setUpMapIfNeeded() {

        if (mMapFragment == null) {

            mMapFragment = SupportMapFragment.newInstance();
            FragmentTransaction fragmentTransaction =
                            getChildFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.map, mMapFragment);
            fragmentTransaction.commit(); 

            setUpMap();
        }
    }

    private void setUpMap() {       

        GoogleMap map = mMapFragment.getMap();  

        // map is null!

    }

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

center_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" >

    <FrameLayout
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </FrameLayout>

    <Button
        android:id="@+id/btn_loc"
        android:layout_width="60dp"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:background="@drawable/locbtn" />

</RelativeLayout>

【问题讨论】:

    标签: android android-maps-v2


    【解决方案1】:

    FragmentTransaction 上的commit() 不会立即执行其操作。当您调用setUpMap() 时,onCreateView() 将不会在SupportMapFragment 上被调用,因此存在 还不是地图。

    一种方法是不使用嵌套片段,而是选择让CenterMapFragment 扩展SupportMapFragment,在这种情况下,getMap() 应该在onCreateView() 之后的任何时间工作(例如,onActivityCreated())。

    【讨论】:

    • 如果CenterMapFragment 扩展SupportMapFragment,如何将地图设置为FrameLayout?我必须改变布局?
    • @jul:一种方法是让CenterMapFragment 首先实现一个名为super.onCreateView()onCreateView(),以获取SupportMapFragment 创建的任何内容。然后它将创建FrameLayout 并将super-created View 添加为FrameLayout 的子代。然后它将从onCreateView() 返回FrameLayout。这将SupportMapFragment 的内容包装在CenterMapFragment 想要的任何内容中。或者,让CenterMapFragment 只是一个普通的Fragment 并使用MapView 而不是SupportMapFragment。或者,找一个更好的时间使用您当前的代码致电setUpMap()
    • @CommonsWare 的上述第一种方法比尝试直接使用 MapView 更容易。 MapView 要求您将其所有生命周期方法转发给它并自己运行 MapsInitializer.initialize(...) 代码。
    • 扩展 SupportMapFragment 并从 onCreateView() 调用 super 不起作用。还是NullPointerException~!
    【解决方案2】:

    在以下链接中,MapView 被用作 CommonsWare 在他评论的最后部分建议的:

    http://ucla.jamesyxu.com/?p=287

    public class MapFragment extends Fragment {
    
        MapView m;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, 
                Bundle savedInstanceState) {
            // inflat and return the layout
            View v = inflater.inflate(R.layout.map_fragment, container, false);
            m = (MapView) v.findViewById(R.id.mapView);
            m.onCreate(savedInstanceState);
    
            return v;
        }
    
        @Override
        public void onResume() {
            super.onResume();
            m.onResume();
        }
    
        @Override
        public void onPause() {
            super.onPause();
            m.onPause();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            m.onDestroy();
        }
    
        @Override
        public void onLowMemory() {
            super.onLowMemory();
            m.onLowMemory();
        }
    }
    

    我希望这些会有所帮助。

    【讨论】:

      【解决方案3】:

      打电话

      fragmentTransaction.commit();
      

      是异步的,当你从它返回时地图还没有准备好。只需调用

      getFragmentManager().executePendingTransactions();
      

      作为下一行,这将使它同步并为下一条指令执行它以获取完成的地图。如果您担心花费的时间,请将整个初始化放入 AsyncTask,并在地图初始化时向用户显示进度指示器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-22
        • 2014-12-23
        相关资源
        最近更新 更多