shubha
shubha

Reputation: 1

MapFragment inside Fragment is not loading properly on second time opening of the fragment

I have a mapFragment inside a fragment along with other views, When i am opening the fragment for first time, its working normal, but reopening the fragment leads to a blank (White) screen..

Does anybody have the same problem? or anyone knows how to solve this.. Kindly help

public class CostEstimationFragment extends Fragment implements OnMapReadyCallback{
private GoogleMap mMap;
MapFragment mapFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
if (rootView != null) {
        ViewGroup parent = (ViewGroup) rootView.getParent();
        if (parent != null)
            parent.removeView(rootView);
    }
    try {
        if(savedInstanceState==null){
        rootView = inflater.inflate(R.layout.abc_layout, container,
                false);
        }

    } catch (InflateException e) {
        e.printStackTrace();

    }
    if(mMap==null)
    mMap = getMapFragment().getMap();
    mMap.clear();

    }

XML of the respective class abc_layout.xml

<ScrollView>
<RelativeLayout>
<ListView/>

<LinearLayout
android:id="@+id/mapviewLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="50dp"
android:orientation="vertical" 
android:layout_below="@+id/estimateLayout"
android:padding="10dp"
android:background="@color/white"
android:elevation="2dp">


  <fragment
    android:id="@+id/map"
    class="com.google.android.gms.maps.MapFragment"
    android:layout_width="match_parent"
    android:layout_height="300dp"/> 



 </LinearLayout>

 <RelativeLayout/>
 <ScrollView/>

Update-1 After reopening the Fragment i am getting below errors 09-27 10:34:45.391: E/AndroidRuntime(18483): FATAL EXCEPTION: main 09-27 10:34:45.391: E/AndroidRuntime(18483): Process: com.radtek.tvms, PID: 18483 09-27 10:34:45.391: E/AndroidRuntime(18483): java.lang.NullPointerException 09-27 10:34:45.391: E/AndroidRuntime(18483): at com.radtek.tvms.CostEstimationFragment.onCreateView(CostEstimationFragment.java:283) 09-27 10:34:45.391: E/AndroidRuntime(18483): at android.app.Fragment.performCreateView(Fragment.java:1700) 09-27 10:34:45.391: E/AndroidRuntime(18483): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890) 09-27 10:34:45.391: E/AndroidRuntime(18483): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062) 09-27 10:34:45.391: E/AndroidRuntime(18483): at android.app.BackStackRecord.run(BackStackRecord.java:684) 09-27 10:34:45.391: E/AndroidRuntime(18483): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447) 09-27 10:34:45.391: E/AndroidRuntime(18483): at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443) 09-27 10:34:45.391: E/AndroidRuntime(18483): at android.os.Handler.handleCallback(Handler.java:733) 09-27 10:34:45.391: E/AndroidRuntime(18483): at android.os.Handler.dispatchMessage(Handler.java:95) 09-27 10:34:45.391: E/AndroidRuntime(18483): at android.os.Looper.loop(Looper.java:136) 09-27 10:34:45.391: E/AndroidRuntime(18483): at android.app.ActivityThread.main(ActivityThread.java:5027) 09-27 10:34:45.391: E/AndroidRuntime(18483): at java.lang.reflect.Method.invokeNative(Native Method) 09-27 10:34:45.391: E/AndroidRuntime(18483): at java.lang.reflect.Method.invoke(Method.java:515) 09-27 10:34:45.391: E/AndroidRuntime(18483): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:838) 09-27 10:34:45.391: E/AndroidRuntime(18483): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:654) 09-27 10:34:45.391: E/AndroidRuntime(18483): at dalvik.system.NativeStart.main(Native Method)

I am using NavigationDrawer to do fragment transaction, So from onItemClickListerner of the BaseActivity i am calling this fragment,

        if(title.equalsIgnoreCase("COSTESTIMATION")) {

        fragment=new CostEstimationFragment();
        }

        if (fragment != null) {
        FragmentManager fm = getFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();

        Fragment f = getFragmentManager().findFragmentById(
                R.id.frame_container);

        // fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

        ft = fm.beginTransaction();
        if (f != null) {
            ft.hide(f);
        }
        ft.add(R.id.frame_container, fragment);
                    ft.addToBackStack(null);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.commit();

UPDATE-2 added

if(fragment instanceof CostEstimationFragment){
            ft.replace(R.id.frame_container, fragment);
        }

i need to keep track of all other fragments opened to give a proper navigation to the app, so i just changed ft.replace(R.id.frame_container, fragment); for this fragment..

Now getting below errors in LogCat

  09-27 19:06:47.243: W/System.err(15481): android.view.InflateException:                   Binary XML file line #149: Error inflating class fragment
  09-27 19:06:47.243: W/System.err(15481):  at       android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:756)
  09-27 19:06:47.243: W/System.err(15481):  at       android.view.LayoutInflater.rInflate(LayoutInflater.java:798)
  09-27 19:06:47.243: W/System.err(15481):  at       android.view.LayoutInflater.rInflate(LayoutInflater.java:801)
  09-27 19:06:47.243: W/System.err(15481):  at       android.view.LayoutInflater.rInflate(LayoutInflater.java:801)
  09-27 19:06:47.243: W/System.err(15481):  at       android.view.LayoutInflater.inflate(LayoutInflater.java:520)
  09-27 19:06:47.243: W/System.err(15481):  at       android.view.LayoutInflater.inflate(LayoutInflater.java:425)
  09-27 19:06:47.243: W/System.err(15481):  at       com.radtek.tvms.CostEstimationFragment.onCreateView(CostEstimationFragment.java:      278)
  09-27 19:06:47.243: W/System.err(15481):  at       android.app.Fragment.performCreateView(Fragment.java:1700)
  09-27 19:06:47.243: W/System.err(15481):  at       android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890)
  09-27 19:06:47.243: W/System.err(15481):  at       android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
  09-27 19:06:47.243: W/System.err(15481):  at       android.app.BackStackRecord.run(BackStackRecord.java:684)
  09-27 19:06:47.243: W/System.err(15481):  at       android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
  09-27 19:06:47.243: W/System.err(15481):  at       android.app.FragmentManagerImpl$1.run(FragmentManager.java:443)
  09-27 19:06:47.243: W/System.err(15481):  at       android.os.Handler.handleCallback(Handler.java:733)
  09-27 19:06:47.253: W/System.err(15481):  at       android.os.Handler.dispatchMessage(Handler.java:95)
  09-27 19:06:47.253: W/System.err(15481):  at       android.os.Looper.loop(Looper.java:136)
  09-27 19:06:47.253: W/System.err(15481):  at       android.app.ActivityThread.main(ActivityThread.java:5027)
  09-27 19:06:47.253: W/System.err(15481):  at       java.lang.reflect.Method.invokeNative(Native Method)
  09-27 19:06:47.253: W/System.err(15481):  at       java.lang.reflect.Method.invoke(Method.java:515)
  09-27 19:06:47.253: W/System.err(15481):  at       com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:838)
  09-27 19:06:47.253: W/System.err(15481):  at       com.android.internal.os.ZygoteInit.main(ZygoteInit.java:654)
  09-27 19:06:47.253: W/System.err(15481):  at       dalvik.system.NativeStart.main(Native Method)
  09-27 19:06:47.253: W/System.err(15481): Caused by:       java.lang.IllegalArgumentException: Binary XML file line #149: Duplicate id       0x7f0b00aa, tag null, or parent id 0x7f0b00a9 with another fragment for com.google.android.gms.maps.MapFragment
  09-27 19:06:47.253: W/System.err(15481):  at       android.app.Activity.onCreateView(Activity.java:4801)
  09-27 19:06:47.253: W/System.err(15481):  at       android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:732)
  09-27 19:06:47.253: W/System.err(15481):  ... 21 more
  09-27 19:06:47.253: D/Network(15481): Network
  09-27 19:06:47.263: D/CostEstimationFragment(15481): sdk: 19
  09-27 19:06:47.263: D/CostEstimationFragment(15481): release: 4.4.2
  09-27 19:06:47.263: D/CostEstimationFragment(15481): using       getFragmentManager
  09-27 19:06:49.195: D/AndroidRuntime(15481): Shutting down VM
  09-27 19:06:49.195: W/dalvikvm(15481): threadid=1: thread exiting with       uncaught exception (group=0x42072ba8)
  09-27 19:06:49.195: E/AndroidRuntime(15481): FATAL EXCEPTION: main
  09-27 19:06:49.195: E/AndroidRuntime(15481): Process: com.radtek.tvms,       PID: 15481
  09-27 19:06:49.195: E/AndroidRuntime(15481):       java.lang.IllegalStateException: The specified child already has a parent. You       must call removeView() on the child's parent first.
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       android.view.ViewGroup.addViewInner(ViewGroup.java:3562)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       android.view.ViewGroup.addView(ViewGroup.java:3415)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       android.view.ViewGroup.addView(ViewGroup.java:3360)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       android.view.ViewGroup.addView(ViewGroup.java:3336)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       android.app.FragmentManagerImpl.moveToState(FragmentManager.java:901)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       android.app.BackStackRecord.run(BackStackRecord.java:684)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       android.app.FragmentManagerImpl$1.run(FragmentManager.java:443)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       android.os.Handler.handleCallback(Handler.java:733)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       android.os.Handler.dispatchMessage(Handler.java:95)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       android.os.Looper.loop(Looper.java:136)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       android.app.ActivityThread.main(ActivityThread.java:5027)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       java.lang.reflect.Method.invokeNative(Native Method)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       java.lang.reflect.Method.invoke(Method.java:515)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:838)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:654)
  09-27 19:06:49.195: E/AndroidRuntime(15481):  at       dalvik.system.NativeStart.main(Native Method)

Upvotes: 0

Views: 591

Answers (2)

Hiren Patel
Hiren Patel

Reputation: 52800

I have done this way:

Always remove MapFragment on onDestroyView() to prevent InflateException.

onCreateView

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){
  if (view != null) {
       ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null)
             parent.removeView(view);
        }
        try
        {
            view = inflater.inflate(R.layout.fragment_map_layout,null);
            MapFragment mapFragment = (MapFragment) getActivity().getFragmentManager()
                    .findFragmentById(R.id.map);
            mapFragment.getMapAsync(this);
        }catch (InflateException e) {
        /* map is already there, just return view as it is */
        }
    return view;
}

onDestroyView

@Override
public void onDestroyView() {
  super.onDestroyView();
        MapFragment mapFragment = (MapFragment) getActivity().getFragmentManager()
                .findFragmentById(R.id.map);

if (mapFragment != null){
     getActivity().getFragmentManager().beginTransaction().remove(mapFragment).commit();
    }
}

Hope this would help you.

Upvotes: 2

waleedsarwar86
waleedsarwar86

Reputation: 2374

implement OnMapReadyCallback interface in your fragment then Edit your code like below

if(mMap==null){
  getMapFragment().getMapAsync(this);
  //remove mMap.clear();
 }
@Override
protected void onStart() {
    super.onStart();
    if(mMap==null){
      getMapFragment().getMapAsync(this);

   }
}
@Override
public void onMapReady(GoogleMap map) {
    mMap=map;
}

And Also change this line:

ft.add(R.id.frame_container, fragment);

to

ft.replace(R.id.frame_container, fragment);

Upvotes: 0

Related Questions