Switching from fragment with map fragment leaves a black screen
Asked Answered
C

9

14

I have added a full-screen map fragment to one of my three tabbed fragments. Everything works great apart from an issue I'm experiencing with switching between the tabs.

Each time I switch from the fragment with the map, to one of the other fragments, I get a black screen for like 0.2 seconds. It seems to be a similar issue to the problems with scrolling in an activity with a map fragment.

I've tried adding a transparent view other the top of the map as others have suggested, but it didn't help.

This is my xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ParkMapFragment">

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

And this is my code:

public class ParkMapFragment extends Fragment {
    public ParkMapFragment() {
        // Required empty public constructor
    }

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

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

        getActivity().setTitle("Map");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.fullParkMap);
        if (mapFragment != null) {
            getFragmentManager().beginTransaction().remove(mapFragment).commit();
        }
    }
}

Anyone have any suggestions?

Cramoisy answered 17/3, 2016 at 19:18 Comment(1)
Had you find the solution.Sill
K
7

Check if the view is null, and if not, remove it from its parent view. That way, you won't see the black screen.

Try the code below.

Fragment:

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class ExhibhitionMap2  extends Fragment implements OnMapClickListener,OnMarkerClickListener{

    View v;
    private  GoogleMap mMap;
    FragmentManager fragmentManager;

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

    //   android = inflater.inflate(R.layout.activity_exhibhition_map, container, false);

         if (v != null) {
                ViewGroup parent = (ViewGroup) v.getParent();
                if (parent != null)
                    parent.removeView(v);
            }
            try {
                 v = inflater.inflate(R.layout.activity_exhibhition_map, container, false);
            } catch (InflateException e) {
                /* map is already there, just return view as it is */
            }

         setUpMapIfNeeded();        
         return v;
     }

     /***** Sets up the map if it is possible to do so *****/
        public  void setUpMapIfNeeded() {
            // Do a null check to confirm that we have not already instantiated the map.
            if (mMap == null) {


                mMap = ((SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.map2)).getMap();

                // Check if we were successful in obtaining the map.
                if (mMap != null)
                {
                    mMap.setOnMapClickListener(this);
                    mMap.setOnMarkerClickListener((OnMarkerClickListener) this);

                     MarkerOptions marker = new MarkerOptions().position(new LatLng(36.011513,-115.174853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
                             .title("P-1");

                     MarkerOptions marker01 = new MarkerOptions().position(new LatLng(36.111513,-115.204853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
                             .title("P-2");

                     MarkerOptions marker02 = new MarkerOptions().position(new LatLng(36.051513,-115.154853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
                             .title("P-3");


                     MarkerOptions marker03 = new MarkerOptions().position(new LatLng(36.057513,-115.344853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
                             .title("P-4");

                     MarkerOptions marker1 = new MarkerOptions().position(new LatLng(36.081513,-115.224853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
                             .title("F-1");

                     MarkerOptions marker2 = new MarkerOptions().position(new LatLng(36.051513,-115.334853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
                             .title("F-2");

                     MarkerOptions marker3 = new MarkerOptions().position(new LatLng(36.101513,-115.124853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
                             .title("F-1");

                     MarkerOptions marker4 = new MarkerOptions().position(new LatLng(36.031513,-115.154853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
                             .title("F-2");

                     MarkerOptions marker5 = new MarkerOptions().position(new LatLng(36.081513,-115.194853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
                             .title("F-2");


                     mMap.addMarker(marker);
                     mMap.addMarker(marker01);
                     mMap.addMarker(marker02);
                     mMap.addMarker(marker03);

                     mMap.addMarker(marker1);
                     mMap.addMarker(marker2);
                     mMap.addMarker(marker3);
                     mMap.addMarker(marker4);

                     mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(36.051513,-115.174853), 10.0f));

                }

            }
        }

    @Override
    public boolean onMarkerClick(Marker marker) {

        /*Toast.makeText(getActivity(),
                  "" + marker.getTitle(), Toast.LENGTH_LONG)
                  .show();*/

        marker.showInfoWindow();

        return false;
    }

    @Override
    public void onMapClick(LatLng arg0) {
        // TODO Auto-generated method stub

    }

    public void onDestroy() {
        super.onDestroy();
    }

}

XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.istride.mmps.ContactActivity" >



    <RelativeLayout
        android:id="@+id/relativeLayout1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tableLayout1"
        android:visibility="gone"
        android:layout_margin="10dp" >

        <TextView
            android:id="@+id/tv_Title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:text="Bharati Vidyapeeth University's"
            android:textColor="@color/black_text_color"
            android:textSize="@dimen/Large_Size" />

        <TextView
            android:id="@+id/tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
             android:layout_below="@+id/tv_Title"
            android:text="Department of Information Technology and Management "
            android:textColor="@color/black_text_color"
            android:textSize="@dimen/small_size" />

        <View
            android:id="@+id/view2"
            android:layout_width="fill_parent"
            android:layout_height="2dp"
            android:layout_below="@+id/tv"
            android:layout_marginTop="10dp"
            android:background="@color/blue_background" />

         <RelativeLayout
        android:id="@+id/relative"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/view2"
         android:layout_marginTop="10dp"
        android:background="@color/gray_home">

        <TextView
            android:id="@+id/textVi1"
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/tv_add"
            android:layout_alignParentTop="true"
            android:background="@color/blue_background"
            android:paddingBottom="2dp"
            android:paddingLeft="8dp"
            android:paddingRight="13dp"
            android:paddingTop="2dp"
            android:gravity="center_vertical"

            android:text="ADDRESS "
            android:textColor="@color/white_text_color"
            android:textSize="@dimen/Medium_size"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/tv_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_marginLeft="10dp"
            android:layout_toRightOf="@+id/textVi1"
            android:paddingBottom="2dp"
            android:paddingTop="2dp"
            android:text="2nd Floor, Architecture Building, Bharati Vidyapeeth Campus, Dhankawadi, Pune-411043"
            android:textColor="@color/black_text_color"
            android:textSize="@dimen/Medium_size" />

        </RelativeLayout>

         <RelativeLayout
        android:id="@+id/relativeLayout_call"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/relative"
         android:layout_marginTop="10dp"
        android:background="@color/gray_home">

        <TextView
            android:id="@+id/textView1"
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/tv_school_office_num"
            android:layout_alignParentTop="true"
            android:background="@color/blue_background"
            android:paddingBottom="2dp"
            android:paddingLeft="8dp"
            android:paddingRight="13dp"
            android:paddingTop="2dp"
            android:text="PHONE "
            android:gravity="center_vertical"
            android:textColor="@color/white_text_color"
            android:textSize="@dimen/Medium_size"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/tv_school_office_num"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
        android:gravity="center_vertical"
            android:layout_alignParentTop="true"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="5dp"
            android:layout_toRightOf="@+id/textView1"

            android:layout_toLeftOf="@+id/imageView2"
             android:textColor="@color/black_text_color"
              android:paddingTop="2dp"
               android:textSize="@dimen/Medium_size"
        android:paddingBottom="2dp"
            android:text="+91 989898989 asasa asas asasas ass  sdsd asas asas ass assas asas ass "  />

        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="3dp"
            android:src="@drawable/ic_call" />
        </RelativeLayout>

         <RelativeLayout
        android:id="@+id/relativeLayout_Email"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/relativeLayout_call"
         android:layout_marginTop="10dp"
        android:background="@color/gray_home">

        <TextView
            android:id="@+id/tex1"
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/imageView1"
            android:layout_alignParentTop="true"
            android:background="@color/blue_background"
            android:gravity="center_vertical"
            android:paddingBottom="2dp"
            android:paddingLeft="8dp"
            android:paddingRight="13dp"
            android:paddingTop="2dp"
            android:text="EMAIL  "
            android:textColor="@color/white_text_color"
            android:textSize="@dimen/Medium_size"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/tv_school_office_email"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
              android:layout_alignBottom="@+id/imageView1"
            android:layout_alignParentTop="true"
            android:layout_marginLeft="10dp"
             android:gravity="center_vertical"
            android:layout_toRightOf="@+id/tex1"
             android:textColor="@color/black_text_color"
              android:paddingTop="2dp"
        android:paddingBottom="2dp"
         android:textSize="@dimen/Medium_size"
            android:text="[email protected]" />

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="3dp"
            android:src="@drawable/ic_email" />

        </RelativeLayout>





    </RelativeLayout>
 <fragment
             android:id="@+id/map2"
             android:layout_width="fill_parent"
             android:layout_height="fill_parent"

             android:layout_alignParentRight="true"

             android:layout_marginTop="10dp"
             class="com.google.android.gms.maps.SupportMapFragment"
             android:background="@color/gray_color"
             android:paddingBottom="5dp"
             android:layout_above="@+id/footer"
             android:textSize="@dimen/small_size" />

   <RelativeLayout
        android:id="@+id/footer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
         android:layout_alignParentBottom="true"
         android:layout_marginBottom="10dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true" >


 <TextView
        android:id="@+id/blue"
        android:layout_width="20dp"
        android:layout_height="20dp"

        android:background="#0000FF"
        android:gravity="center"
        android:layout_margin="10dp"

        android:textColor="@color/black_text_color"
        android:textSize="@dimen/small_size"
        android:textStyle="bold" />

 <TextView
        android:id="@+id/parking"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
      android:layout_toRightOf="@+id/blue"
        android:layout_alignTop="@+id/blue"
         android:layout_alignBottom="@+id/blue"
         android:gravity="center_vertical"
      android:text="Parking"
        android:textColor="@color/black_text_color"
        android:textSize="@dimen/Medium_size"
        android:textStyle="bold" />


  <TextView
        android:id="@+id/cyc"
        android:layout_width="20dp"
        android:layout_height="20dp"

        android:background="#00FFFF"
        android:gravity="center"
        android:layout_margin="10dp"
        android:layout_toRightOf="@+id/parking"
        android:textColor="@color/black_text_color"
        android:textSize="@dimen/small_size"
        android:textStyle="bold" />

 <TextView
        android:id="@+id/footer2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
      android:layout_toRightOf="@+id/cyc"
        android:layout_alignTop="@+id/cyc"
         android:layout_alignBottom="@+id/cyc"
         android:gravity="center_vertical"
      android:text="Food"
        android:textColor="@color/black_text_color"
        android:textSize="@dimen/Medium_size"
        android:textStyle="bold" />



</RelativeLayout>
</RelativeLayout>
Konstanz answered 24/3, 2016 at 6:3 Comment(0)
T
2
   @Override
public void onDestroyView() {
    super.onDestroyView();
    SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.fullParkMap);
    if (mapFragment != null) {
        getFragmentManager().beginTransaction().remove(mapFragment).commit();
    }
}

right here you are removing the fragment without replacing it. I would use .replace instead with a new fragment.

Something like this:

getFragmentManager().beginTransaction().replace(R.id.your_placeholder, new CustomFragment(), "cstmFragID").commit();
Talton answered 18/3, 2016 at 0:16 Comment(4)
That code is to avoid this issue. It doesn't have an effect on the problem I'm having unfortunately.Cramoisy
where's the code where you are using .add to replace the fragment?Talton
I'm still fairly new to Android, but I guess onCreateView is replacing the entire fragment (with the map fragment within)? The map is definitely reloading each time I return to the fragment, so I suppose that must be what's happening.Cramoisy
@Cramoisy I think this should solve it. You are not supposed to override onDestroyView at all. Just replace the fragment (with the above code) when you want it to be out of the view. The rest is taken care of.Inelegance
M
2

This is a known issue. For the meantime, you may use work around by placing another view on top of the map that uses a background color that is the same as its container is. This makes the map smoothly come in once its ready.

SupportMapFragment mapFragment = SupportMapFragment.newInstance(new  GoogleMapOptions().zOrderOnTop(true));
Mush answered 18/3, 2016 at 15:55 Comment(1)
The problem isn't with the map appearing, it's when I switch fragments (it turns black for a few milliseconds).Cramoisy
L
2

i would recommend you to use MapView instead of SupportFragment to avoid nested fragment For details answer look at the following post

Should I use MapView or MapFragment

Now your ParkFragment be look like

MapFragment.java

public class MapFragment extends Fragment implements OnMapReadyCallback {

    private MapView mMapView;
    private GoogleMap mGoogleMap;

    public MapFragment() {
        // Required empty public constructor
    }

    public static MapFragment newInstance() {
        MapFragment fragment = new MapFragment();
        return fragment;
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_map, container, false);
        mMapView = (MapView) rootView.findViewById(R.id.map);
        mMapView.onCreate(savedInstanceState);
        mMapView.getMapAsync(this);

        return rootView;
    }

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


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

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


    @Override
    public void onMapReady(GoogleMap googleMap) {
        googleMap.getUiSettings().setZoomControlsEnabled(true);

    }
}

fragment_map.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    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" />

</FrameLayout>
Linguistic answered 24/3, 2016 at 8:17 Comment(1)
Just gave this a try, and unfortunately it has the same problem.Cramoisy
F
2

The problem is possibly because it is recreating Fragment which causes the Black screen. If you are using ViewPager then you can use

// Note that you must set adapter before this line otherwise it can cause NullPointerException
// Or add null check on getAdapter if required
mViewPager.setOffscreenPageLimit(mViewPager.getAdapter().getCount());

It will force ViewPager not to create Fragments second time. For sure, it takes more memory but I believe it is more efficient when using less tabs so I normally do this to avoid recreation of fragments.

Secondly I would suggest to remove these lines from onDestroy:

SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.fullParkMap);
if (mapFragment != null) {
    getFragmentManager().beginTransaction().remove(mapFragment).commit();
}

And overcome this issue by updating onCreateView as this:

private View mView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    if (mView == null) {
        mView = inflater.inflate(R.layout.fragment_map, container, false);
    }
    return mView;
}

It will not inflate layout every time so you will not face Duplicate ID, tag null, or parent id with another fragment for com.google.android.gms.maps.MapFragment issue.
But make sure you pass false in attachToRoot (last argument of inflater.inflate) otherwise you may get exceptions like The specified child already has a parent

Last thing, when using MapFragment inside Fragment, or in other words, when using Nested Fragments, I would recommend use getChildFragmentManager() instead of getFragmentManager() to avoid unexpected issues.
Because as the documentation says:
getFragmentManager: Return the FragmentManager for interacting with fragments associated with this fragment's activity. Note that this will be non-null slightly before getActivity(), during the time from when the fragment is placed in a FragmentTransaction until it is committed and attached to its activity. If this Fragment is a child of another Fragment, the FragmentManager returned here will be the parent's getChildFragmentManager().
getChildFragmentManager: Return a private FragmentManager for placing and managing Fragments inside of this Fragment.

Flaky answered 26/3, 2016 at 10:53 Comment(1)
Thanks, u had save my day !Marymarya
V
1

As you always replace fragment then map gets always created then workaround for this would be load your map fragment only once, rest of the time just show/hide your fragment (as if you are showing tabbed fragments).

Valorize answered 23/3, 2016 at 8:20 Comment(0)
N
1

Have you tried to hide and show fragment (instead of remove/adding it) ?

private FragmentA fragmentA;
private FragmentB fragmentB;
private FragmentC fragmentC;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (savedInstanceState == null) {
        fragmentA = FragmentA.newInstance("foo");
        fragmentB = FragmentB.newInstance("bar");
        fragmentC = FragmentC.newInstance("baz");
    }
}

In your case you might change it to ParkMapFragment etc.

protected void displayFragmentA() {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    if (fragmentA.isAdded()) { // if the fragment is already in container
        ft.show(fragmentA);
    } else { // fragment needs to be added to frame container
        ft.add(R.id.flContainer, fragmentA, "A");
    }
    // Hide fragment B
    if (fragmentB.isAdded()) { ft.hide(fragmentB); }
    // Hide fragment C
    if (fragmentC.isAdded()) { ft.hide(fragmentC); }
    // Commit changes
    ft.commit();
}

source: https://github.com/codepath/android_guides/wiki/Creating-and-Using-Fragments

Nest answered 27/3, 2016 at 11:3 Comment(0)
N
1

Try this inside createView:

if (v != null) {
    ViewGroup parent = (ViewGroup) v.getParent();
    if (parent != null)
        parent.removeView(v);
}
Nightwalker answered 29/3, 2016 at 4:59 Comment(0)
N
0

You should make the transition of fragments by this way:

Fragment fragment = new YourFragmentToShow();
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment, TAG).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit(); 

With TRANSIT_FRAGMENT_FADE Fragment should simply fade in or out; that is, no strong navigation associated with it except that it is appearing or disappearing for some reason.

Use it when you replace the fragment with map by another fragment, in other case I recomend the common use, without (.setTransition...):

Fragment fragment = new YourFragmentToShow();
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment, TAG).commit(); 
Nimrod answered 19/11, 2016 at 18:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.