Подтвердить что ты не робот

Попытка удалить фрагмент из представления дает мне NullPointerException на mNextAnim

У меня есть 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, определяемый как идентификатор корня FrameLayout макета MapInfoFragment xml, поэтому я думаю, что map_info_layout и map_info указывали на одно и то же.

Обновление 2: Мое решение

Оказалось, что у меня было MapInfoFragment расширение android.support.v4.app.Fragment вместо android.app.Fragment, и я использовал android.app.FragmentTransaction вместо android.support.v4.app.FragmentTransaction. Переключил все на android.app., так как меня не интересует более старая совместимость с устройством. Спасибо Fllo.

Обновление 3: Общее решение

Остановить попытку скрыть нулевые объекты

4b9b3361

Ответ 1

Я знаю, что вы решили это самостоятельно, но я хочу объяснить, как эта ошибка происходит, поскольку это произошло со мной.

В основном вы вызываете hide(), remove() и т.д. с нулевым значением.

Ошибка не очевидна, и трассировка стека не возникает из ваших собственных источников, когда это происходит, поэтому нет ничего тривиального, чтобы понять, что это такое.

Ответ 2

Это также происходит, когда вы вызываете FragmentManager.popBackstack(), не имея фрагмента в backstack.

Ответ 3

это связано с тем, что вы добавляете или показываете или скрываете фрагмент, который теперь имеет значение null, попробуйте проверить, является ли оно нулевым, прежде чем вы его используете!

Ответ 4

Моя проблема заключалась в том, что FragmentManager getFragments() иногда возвращает список, в котором некоторые фрагменты являются нулевыми, и я удалял эти нулевые фрагменты.

Ответ 5

Это случилось со мной только тогда, когда из одного из фрагментов в ящике навигации я показал DialogFragment, используя

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

Если вместо этого я использовал

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

этого не произошло.

ПРИМЕЧАНИЕ. Ошибка при отображении или закрытии диалогового окна не произошла, но при смене на другой фрагмент из ящика навигации.

Ответ 6

Правильно вызовите show() и скройте()...

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