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

时间:2014-03-18 19:57:24

标签: android android-fragments android-studio

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

更新1

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

更新2:我的解决方案

原来我MapInfoFragment延长了android.support.v4.app.Fragment而不是android.app.Fragment而我正在使用android.app.FragmentTransaction代替android.support.v4.app.FragmentTransaction。将所有内容切换为android.app.,因为我对旧设备兼容性不感兴趣。谢谢Fllo。

更新3:一般解决方案

停止尝试隐藏空对象

7 个答案:

答案 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();
                }