试图从视图中删除片段给我mNextAnim NullPointerException

我有3个片段,一个NavigationDrawer,一个MapFragment和一个用户定义的“MapInfoFragment”。 我希望“MapInfoFragment”在某些事件上在MapFragment顶部显示为半透明,并在其他事件上消失。 我真的不在乎是否我每次都完全删除片段并创build一个新片段,或者只是更改显示的可见性和信息。 目前我只是试图使用FragmentManager的.hide()函数,但我也试过.remove和.detach具有类似的结果。

错误:

03-18 14:28:10.965 24711-24711/com.[packageName].asTest D/AndroidRuntime﹕ Shutting down VM 03-18 14:28:10.965 24711-24711/com.[packageName].asTest E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.[packageName].asTest, PID: 24711 java.lang.NullPointerException: Attempt to write to field 'int android.app.Fragment.mNextAnim' on a null object reference at android.app.BackStackRecord.run(BackStackRecord.java:658) at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447) at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 

activity_main.xml中:

 <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.[packageName].asTest.MainActivity"> <!-- As the main content view, the view below consumes the entire space available using match_parent in both dimensions. --> <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" > <fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:map="http://schemas.android.com/apk/res-auto" android:id="@+id/map" android:name="com.google.android.gms.maps.MapFragment" android:layout_width="match_parent" android:layout_height="match_parent" map:cameraZoom="8" map:mapType="satellite" map:uiRotateGestures="false" android:layout_gravity="center_horizontal|top" /> </FrameLayout> <fragment android:id="@+id/navigation_drawer" android:layout_width="@dimen/navigation_drawer_width" android:layout_height="match_parent" android:layout_gravity="start" android:name="com.[packageName].asTest.NavigationDrawerFragment" tools:layout="@layout/simple_list_item_1" /> <fragment android:id="@+id/map_info" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.[packageName].asTest.MapInfoFragment" /> </android.support.v4.widget.DrawerLayout> 

出错代码:

 FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.hide(getFragmentManager().findFragmentById(R.id.map_info)); ft.commit(); 

更新1

我将map_info_layout更改为map_info并且我得到的错误没有任何变化。 我之前已经把map_info_layout定义为MapInfoFragment的布局xml的根FrameLayout的id,所以我认为map_info_layoutmap_info指向了相同的东西。

更新2:我的解决scheme

原来,我有MapInfoFragment扩展android.support.v4.app.Fragment而不是android.app.Fragment ,我使用android.app.FragmentTransaction而不是android.support.v4.app.FragmentTransaction 。 切换到android.app.一切android.app. 因为我对旧的设备兼容性不感兴趣。 感谢Fllo。

更新3:通用解决scheme

停止尝试隐藏空对象

我知道你已经解决了这个问题,但是我想解释一下这个错误是怎么发生的,因为它发生在我身上。

基本上你用一个空值来调用hide()remove()等等。

这个错误并不明显,当这种情况发生时,堆栈跟踪不是从你自己的源头发出的,所以知道它是什么并不是微不足道的。

当你调用FragmentManager.popBackstack()时,也会发生这种情况,而在后台没有片段。

这是因为您添加或显示或隐藏了一个现在为空的片段,请在使用它之前尝试检查它是否为空!

我的问题是,FragmentManager的getFragments()有时会返回一个列表,其中一些片段为空,我正在删除这些空片段。

它仅在从导航抽屉中的一个片断使用时显示DialogFragment的情况下才发生

 newFragment.show(getFragmentManager(), "dialog"); 

如果我使用了

 newFragment.show(getChildFragmentManager(), "dialog"); 

这没有发生。

注意:当显示或closures对话框时,碰撞没有发生,但当从导航抽屉切换到另一个片段时。

正确地调用show()和hide()…

  private void showFragment(int fragmentIndex, boolean addToBackStack) { FragmentManager fm = getFragmentManager(); FragmentTransaction transaction = fm.beginTransaction(); for (int i = 0; i < fragments.length; i++) { if (i == fragmentIndex) { transaction.show(fragments[i]); } else { transaction.hide(fragments[i]); } } if (addToBackStack) { transaction.addToBackStack(null); } transaction.commit(); }