Failed to change map fragment after fragment refresh

  • I have activity with a navigation box and HomeFragment .

  • HomeFragment contains two nested fragments (child fragments): SupportMapFragment and ActionFragment .

I declare the GoogleMap object sMapas static in HomeFragment , so it can be retrieved and modified using the nested ActionFragment fragment .

Everything works fine in the first run. A map can be manipulated from an ActionFragment . But when HomeFragment is deleted and reloaded at a later point in time, the map can only be modified with HomeFragment (parent fragment), and not from ActionFragment (nested fragment).

I do not understand why something that works in the first instance does not work when the fragment reloads. Below are the codes that I have kept to a minimum for easier understanding.


HomeFragment.java (parent fragment)

public class HomeFragment extends Fragment {

    private static GoogleMap sMap;
    public static GoogleMap getMap() {
        return sMap;
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate layout
        return inflater.inflate(R.layout.f_home, container, false);
    }


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

        // Obtain the GoogleMap object
        try {
            if (sMap == null) {
                sMap = ((SupportMapFragment) getActivity().getSupportFragmentManager()
                        .findFragmentById(R.id.home_map)).getMap();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Load child fragment
        if (savedInstanceState == null) {
            Fragment _actionFragment = new ActionFragment();
            FragmentTransaction _ft = getChildFragmentManager().beginTransaction();
            _ft.replace(R.id.action_container_bottom, _actionFragment);
            _ft.commit();
        }
    }


    @Override
    public void onDestroyView(){
        super.onDestroyView();

        // Remove the map fragment to prevent errors on the next load
        if(sMap != null){
            try {
                getActivity().getSupportFragmentManager()
                            .beginTransaction()
                            .remove(getActivity().getSupportFragmentManager()
                                    .findFragmentById(R.id.home_map))
                            .commit();

                sMap = null;
            } catch (Exception e){}
        }
    }
}

f_home.xml (layout of the parent fragment)

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

    <fragment
        android:id="@+id/home_map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <FrameLayout
        android:id="@+id/action_container_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" />

</RelativeLayout>

ActionFragment.java (nested or child fragment)

public class ActionFragment extends Fragment {
    private static GoogleMap sMap = HomeFragment.getMap();


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

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


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

        // check if map is created successfully or not
        if (sMap != null) {
            sMap.clear();
            sMap.setPadding(0, 0, 0, 300);
            sMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
            sMap.setBuildingsEnabled(false);
            sMap.setMyLocationEnabled(false);
            sMap.getUiSettings().setRotateGesturesEnabled(false);
            sMap.getUiSettings().setTiltGesturesEnabled(false);
            sMap.getUiSettings().setZoomControlsEnabled(false);
            sMap.moveCamera(CameraUpdateFactory.zoomTo(12));
        }
    }
}

Any help would be greatly appreciated as I have been struggling with this for a long time. Thank!

+4
3

. var . , HomeFragment , HomeFragment . .

, , . , . , .

:

((SupportMapFragment) getActivity().getSupportFragmentManager()
                        .findFragmentById(R.id.home_map)).getMap();

, .

+4

, ActionFragment , .

:

1) HomeFragment#onActivityCreated()

  • HomeFragment#sMap - null → findViewById()
  • HomeFragment#sMap= [1]

2) classloader ActionFragment

  • ActionFragment#sMap null → load from HomeFragment.getMap()
  • ActionFragment#sMap= [1]

... ...

3) HomeActivity#onDestroyView()

  • HomeFragment#sMap= null

... home ...

4) HomeFragment#onActivityCreated()

  • HomeFragment#sMap - null → findViewById()
  • HomeFragment#sMap= [2]

ActionFragment , , , , ActionFragment#sMap . () [1].

, :

public class ActionFragment extends Fragment {
    private GoogleMap mMap;

    public void onAttach(Activity activity) {
        super.onAttach(activity);  
        mMap = HomeFragment.getMap();
    }


   public void onDetach() { 
       super.onDetach() {
       mMap = null;
   }
}

ActionFragment HomeFragment.

+7

, , SupportMapFragment, HomeFragment. . docs:

. , . .

f_home.xml

    <!--<fragment
        android:id="@+id/home_map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />-->

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

HomeFragment

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

        // Obtain the GoogleMap object
        try {
            if (sMap == null) {
                /*sMap = ((SupportMapFragment) getActivity().getSupportFragmentManager()
                        .findFragmentById(R.id.home_map)).getMap();*/
                mapFragment = new SupportMapFragment();
                sMap = mapFragment.getMap();
                getChildFragmentManager()
                        .beginTransaction()
                        .replace(R.id.home_map, mapFragment)
                        .commit();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Load child fragment
        if (savedInstanceState == null) {
            Fragment _actionFragment = new ActionFragment();
            FragmentTransaction _ft = getChildFragmentManager().beginTransaction();
            _ft.replace(R.id.action_container_bottom, _actionFragment);
            _ft.commit();
        }
    }


    @Override
    public void onDestroyView(){
        super.onDestroyView();

        // Remove the map fragment to prevent errors on the next load
        if(sMap != null){
            try {
                /*getActivity().getSupportFragmentManager()
                        .beginTransaction()
                        .remove(getActivity().getSupportFragmentManager()
                                .findFragmentById(R.id.home_map))
                        .commit();*/

                getChildFragmentManager()
                        .beginTransaction()
                        .remove(mapFragment)
                        .commit();
                sMap = null;
                mapFragment = null;
            } catch (Exception e){}
        }
    }

ActionFragment GoogleMap, HomeFragment, findFragmentById api.

+3

All Articles