我有3个片段,一个NavigationDrawer,一个MapFragment和一个用户定义的" MapInfoFragment"。我想要" MapInfoFragment"在某些事件上在MapFragment顶部显示为半透明,在其他事件上消失。如果我每次都完全删除片段并创建一个新片段,或者我只是更改显示的可见性和信息,我真的不在乎。目前我只是尝试使用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();
我将map_info_layout
更改为map_info
,并且我得到的错误没有变化。我之前已将map_info_layout
定义为MapInfoFragment布局xml的根FrameLayout的id,所以我认为map_info_layout
和map_info
指向同一个东西
原来我MapInfoFragment
延长了android.support.v4.app.Fragment
而不是android.app.Fragment
而我正在使用android.app.FragmentTransaction
代替android.support.v4.app.FragmentTransaction
。将所有内容切换为android.app.
,因为我对旧设备兼容性不感兴趣。谢谢Fllo。
停止尝试隐藏空对象
答案 0 :(得分:115)
我知道你自己已经解决了这个问题,但我想解释一下这个错误是如何发生的,因为它刚好发生在我身上。
基本上,您使用空值调用hide()
,remove()
等。
错误并不明显,当发生这种情况时,堆栈跟踪并不是来自您自己的来源,因此实现它的目的并非易事。
答案 1 :(得分:8)
当你在没有后台堆叠片段时调用FragmentManager.popBackstack()
时也会发生这种情况。
答案 2 :(得分:5)
这是因为你现在添加,显示或隐藏一个null的片段,在你使用之前尝试检查它是否为null!
答案 3 :(得分:2)
我的问题是FragmentManager的getFragments()有时返回一个列表,其中一些片段为null,我正在删除那些空片段。
答案 4 :(得分:0)
只有当我从导航抽屉中的一个片段中使用
显示DialogFragment时才向我发送信息。newFragment.show(getFragmentManager(), "dialog");
如果我使用了
newFragment.show(getChildFragmentManager(), "dialog");
这没有发生。
注意:在显示或关闭对话框时,但在从导航抽屉更改为另一个片段时,我不会发生崩溃。
答案 5 :(得分:0)
正确调用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();
}
答案 6 :(得分:0)
如果需要使用getSupportFragmentManager(),除了做空值检查外,还必须检查当前是否添加了该片段。如果你只使用空值,它仍然会崩溃。这将起作用:
if (fragment != null && fragment.isAdded()) {
getSupportFragmentManager().beginTransaction().
remove(getSupportFragmentManager().findFragmentById(R.id.fragment_container)).commit();
}