Fragment中的MapFragment在第二次打开片段时没有正确加载

时间:2015-09-26 19:04:29

标签: google-maps android-fragments

我在片段中有一个mapFragment和其他视图,当我第一次打开片段时,它的工作正常,但重新打开片段会导致一个空白(白色)屏幕..

有人有同样的问题吗?或者任何人都知道如何解决这个问题..请帮助

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

    }

相应类abc_layout.xml的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/>

更新-1 重新打开片段后,我遇到了错误 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)

我使用NavigationDrawer来做片段事务,所以从BaseActivity的onItemClickListerner我调用这个片段,

        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 添加

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

我需要跟踪打开的所有其他片段,以便为应用程序提供正确的导航,因此我只更改了此片段的 ft.replace(R.id.frame_container,fragment);

现在降低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)

2 个答案:

答案 0 :(得分:1)

我这样做了:

始终将onDestroyView()上的MapFragment移至阻止 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();
    }
}

希望这会对你有所帮助。

答案 1 :(得分:0)

在片段中实现OnMapReadyCallback接口,然后编辑您的代码,如下所示

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

并且还改变这一行:

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

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