SupportMapFragment's getMap() returns null

2019-02-16 14:41发布

问题:

I'm trying to create a SupportMapFragment dynamically and to put it in a FrameLayout container.

My issue is that mMapFragment.getMap() returns null...

Anybody can help?

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>

回答1:

commit() on a FragmentTransaction does not perform its operations immediately. By the time you call setUpMap(), onCreateView() will not have been called on the SupportMapFragment, and hence there will not yet be a map.

One approach is to not use nested fragments, electing instead to have CenterMapFragment extend SupportMapFragment, in which case getMap() should work any time after onCreateView() (e.g., onActivityCreated()).



回答2:

In the following link MapView is used as CommonsWare suggests in the last part of his comment:

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();
    }
}

I hope these will be helpful.



回答3:

Calling

fragmentTransaction.commit();

is asynchronous, the map won't be ready yet when you return from it. Simply call

getFragmentManager().executePendingTransactions();

as the next line, that will make it synchronous and will execute it for the next instruction to pick up the finished map all right. If you're worried about the time it takes, put the whole initialization into an AsyncTask and show a progress indicator to the user while the map is initializing.