Skip to content Skip to sidebar Skip to footer

Android Drawerlayout With Mapfragment Black Screen When Returning To Map

I've been experimenting with android.support.v4.widget.DrawerLayout and have 4 fragments to choose from the drawer. The map initially loads with no problems however when I open the

Solution 1:

After days of beating my head against the wall I figured out the problem, or should I say problemS. tsp suggested using libraries above which works too however I wanted to get this to work with the Google provided android.support.v4.widget.DrawerLayout.

The issue was 2 fold.

  1. I was using nested fragments and I wasn't removing the child (map) fragment when leaving the ExploreMap fragment. My hiearchy is: Activity(DrawerLayout)-->ExploreMap(A Fragment)-->MapFragment. When opening the drawer and changing fragments I was not removing the MapFragment from the ExploreMap(fragment). The original MapFragment instance remained in memory due to setRetainInstance(true). For reasons I still don't fully understand the original instance of the MapFragment would not re-appear once returning to the ExploreMap fragment. To solve this I assign the MapFragment a String tag I called "mapfrag" when it is initially created and set the variable to be public static. Next in the Activity, where the drawer code is to switch fragments, I do a findFragmentByTag() and test if its null, removing the MapFragment if it is not null.

However #1 only gets you half way as it will get the map to reappear when you go back to the ExploreMap however the underlying GoogleMap from the MapFragment kept returning null to me and I couldn't get the map configured at all.

2) I found this post MapFragment return null. Which recommended extending your own MapFragment and implementing an interface to notify when the MapFragment is done being created, pretty much guaranteeing a non-null GoogleMap.

and WHAMMY!! you have a working google map in googles drawer layout. Here is my complete working code.

MainActivity.java
 if(position == 0){
                exMap = newExploreMap();
                exMap.setRetainInstance(true);
                getFragmentManager().beginTransaction().replace(R.id.content_frame, exMap).commit();
            }
            if(position == 1){  
                //remove map frag here instead of in explore mapFragmentf= getFragmentManager().findFragmentByTag("mapfrag");
                if(f != null){
                     getFragmentManager().beginTransaction().remove(f).commit();
                }

                Msfragment=newMs();
                getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).commit(); 
            }
            if(position == 2){
                Fragmentf= getFragmentManager().findFragmentByTag("mapfrag");
                if(f != null){
                     getFragmentManager().beginTransaction().remove(f).commit();
                }
                Settingsfragment=newSettings();
                getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).commit(); 
            }
            if(position == 3){
                Fragmentf= getFragmentManager().findFragmentByTag("mapfrag");
                if(f != null){
                     getFragmentManager().beginTransaction().remove(f).commit();
                }
                Aboutfragment=newAbout();
                getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).commit(); 
            }

in ExploreMap.java

publicclassExploreMapextendsFragmentimplementsMyMapFragment.MapCallback,  OnInfoWindowClickListener, android.location.LocationListener, OnMapLongClickListener{

     private LocationManager mLocManager;
     private GoogleMap mMap;
     publicstatic MyMapFragment mMapFragment;

@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            Viewv= inflater.inflate(R.layout.explore_map_layout, container, false); 


            FragmentManagerfm= getActivity().getFragmentManager();
            mMapFragment = (MyMapFragment) fm.findFragmentById(R.id.map_framelayout);


            if (mMapFragment == null) {
                mMapFragment = newMyMapFragment();
                mMapFragment.setRetainInstance(true);
                mMapFragment.setMapCallback(this);
                fm.beginTransaction().replace(R.id.map_framelayout, mMapFragment,"mapfrag").commit();
            }

            createMapIfNeeded();

            return v;
        }



        @OverridepublicvoidonMapReady(GoogleMap map) {
            createMapIfNeeded();
        }   

privatevoidcreateMapIfNeeded(){

            if(mLocManager == null){
                mLocManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
                mLocManager.requestLocationUpdates(
                           LocationManager.NETWORK_PROVIDER,
                           MIN_TIME_BW_UPDATES,
                           MIN_DISTANCE_CHANGE_FOR_UPDATES,
                           this);
            }

             //locmanager can return null if no last known locaiton is available.
            location = mLocManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);


            //if a map has not already been instantiated it'll return nullif(mMap == null){
                //instantiate map
                mMap = mMapFragment.getMap();


                //check it has been instantiatedif(mMap != null){
                    mMap.setOnMapLongClickListener(this);
                    mMap.setOnInfoWindowClickListener(this);
                    mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                    mMap.setMyLocationEnabled(true);

                    //Manipulate map here (add coordinates/polylines from trip etc etc.)UiSettingssetting= mMap.getUiSettings();
                    setting.setTiltGesturesEnabled(true);
                    setting.setRotateGesturesEnabled(true);
                    setting.setZoomControlsEnabled(true);
                    setting.setMyLocationButtonEnabled(true);

                    if(location != null){
                    CameraUpdatecu= CameraUpdateFactory.newLatLngZoom(newLatLng(location.getLatitude(), location.getLongitude()), 15);
                    mMap.animateCamera(cu);
                    }
                }
            }  
        }

and now MyMapFragment.java

publicclassMyMapFragmentextendsMapFragment{



      private MapCallback callback;

      publicstaticinterfaceMapCallback
      {
         publicvoidonMapReady(GoogleMap map);
      }

      publicvoidsetMapCallback(MapCallback callback)
      {
        this.callback = callback;
      }

      @OverridepublicvoidonActivityCreated(Bundle savedInstanceState)
      {
          super.onActivityCreated(savedInstanceState);
         if(callback != null) callback.onMapReady(getMap());     
      }


}

CHEERS!!!

Solution 2:

Solution 3:

Easy workaround for this issue found on a mail thread. This solved my issue. Use relative layout and place this transparent view directly over your map fragment. Example :

<?xml version="1.0" encoding="utf-8"?><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><fragmentandroid:id="@+id/map"android:layout_width="match_parent"android:layout_height="match_parent"class="com.google.android.gms.maps.SupportMapFragment"/><Viewandroid:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/transparent" /></RelativeLayout>

Post a Comment for "Android Drawerlayout With Mapfragment Black Screen When Returning To Map"