将setExitTransition用于Fragment时出现NullPointerException

时间:2015-05-08 08:02:21

标签: android android-fragments nullpointerexception transition

我正在尝试动画片段的进入和退出。 setEnterTransition工作正常,但如果我使用setExitTransition,则会抛出nullPointerException。如果我使用setReturnTransition,它就不会显示任何动画。

这就是我所拥有的。

private void showFragment() {
    Fragment fragment = JoinGroupFragment.newInstance();
    FragmentTransaction ft = getFragmentManager().beginTransaction()
            .add(R.id.fragment_container, fragment, JOIN_GROUP_FRAGMENT_TAG);


    if (Build.VERSION.SDK_INT >= 21) {
        Log.i(TAG, "set enter transition");
        fragment.setEnterTransition(new Slide(Gravity.TOP));
//      fragment.setExitTransition(new Slide(Gravity.BOTTOM));
    }

    ft.commit();
}

private void dismissFragment() {
    Fragment joinGroupFragment = getFragmentManager().findFragmentByTag(JOIN_GROUP_FRAGMENT_TAG);
    if (joinGroupFragment != null) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
//      ft.hide(joinGroupFragment);
        ft.remove(joinGroupFragment);
        ft.commit();
    }
}

现在,如果我使用setExitTransition,我会收到以下错误。

  

java.lang.NullPointerException:尝试从字段' int中读取   android.app.Fragment.mContainerId'在null对象引用上               在android.app.BackStackRecord $ 1.onPreDraw(BackStackRecord.java:1131)               在android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)               在android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1970)               在android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)               在android.view.ViewRootImpl $ TraversalRunnable.run(ViewRootImpl.java:5885)               在android.view.Choreographer $ CallbackRecord.run(Choreographer.java:767)               在android.view.Choreographer.doCallbacks(Choreographer.java:580)               在android.view.Choreographer.doFrame(Choreographer.java:550)               在android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:753)               在android.os.Handler.handleCallback(Handler.java:739)               在android.os.Handler.dispatchMessage(Handler.java:95)               在android.os.Looper.loop(Looper.java:135)               在android.app.ActivityThread.main(ActivityThread.java:5254)               at java.lang.reflect.Method.invoke(Native Method)               在java.lang.reflect.Method.invoke(Method.java:372)               在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:903)               在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

我环顾四周,发现有关于此的错误。 https://code.google.com/p/android/issues/detail?id=82832

已发布解决方法。我尝试了同样的事情,但使用FragmentManager而不是supportFragmentManager,但我仍然面临同样的问题。

我尝试过的解决方法

// This is in onCreate().
getFragmentManager().beginTransaction().add(R.id.fragment_container, new Fragment())
                    .addToBackStack("dummy")
                    .commit();
private void showFragment() {
    Fragment fragment = JoinGroupFragment.newInstance();
    FragmentTransaction ft = getFragmentManager().beginTransaction()
            .replace(R.id.fragment_container, fragment, JOIN_GROUP_FRAGMENT_TAG);

    ft.addToBackStack(null);
    // ft.addToBackStack("dummy");
    // ft.addToBackStack("my_backstack); // none of these work
    ft.commit();


    if (Build.VERSION.SDK_INT >= 21) {
        Log.i(TAG, "set enter transition");
        fragment.setEnterTransition(new Slide(Gravity.TOP));
        fragment.setExitTransition(new Slide(Gravity.BOTTOM));
    }

    ft.commit();
}

private void dismissFragment() {
    Fragment joinGroupFragment = getFragmentManager().findFragmentByTag(JOIN_GROUP_FRAGMENT_TAG);
    if (joinGroupFragment != null) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
//      ft.hide(joinGroupFragment);
        ft.remove(joinGroupFragment);
        ft.commit();
    }
}

我知道在Backstack中没有任何片段用于转换,但添加虚拟片段也没有帮助。有没有解决方法呢?

更新

我使用相同的片段而不是虚拟片段。

getFragmentManager().beginTransaction().add(R.id.fragment_container, JoinGroupFragment.newInstance())
                        .addToBackStack("dummy")
                        .commit();
private void showFragment() {
    Fragment fragment = JoinGroupFragment.newInstance();
    FragmentTransaction ft = getFragmentManager().beginTransaction()
            .replace(R.id.fragment_container, fragment, JOIN_GROUP_FRAGMENT_TAG);

    ft.addToBackStack("dummy");
    ft.commit();


    if (Build.VERSION.SDK_INT >= 21) {
        Log.i(TAG, "set enter transition");
        fragment.setEnterTransition(new Slide(Gravity.TOP));
        fragment.setExitTransition(new Slide(Gravity.BOTTOM));
    }

    ft.commit();
}

private void dismissFragment() {
    Fragment joinGroupFragment = getFragmentManager().findFragmentByTag(JOIN_GROUP_FRAGMENT_TAG);
    if (joinGroupFragment != null) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
//      ft.hide(joinGroupFragment);
        ft.remove(joinGroupFragment);
        ft.commit();
    }
}

如果我这样做,当我第一次调用showFragment()时,先前添加的(在onCreate()中)片段显示退出转换,新的片段显示输入转换,但是当我调用dismissFragment()时,它仍然会抛出同样的错误。我一直使用getBackStackEntryCount()记录后台堆栈计数,并在删除片段时显示2,但仍然是错误。

但我不明白第一个片段是如何显示退出过渡的。

我也试过了。

getFragmentManager().beginTransaction().add(R.id.fragment_container, new Fragment())
                        .addToBackStack("dummy")
                        .commit();
private void showFragment() {
    Fragment fragment = JoinGroupFragment.newInstance();
    FragmentTransaction ft = getFragmentManager().beginTransaction()
            .replace(R.id.fragment_container, fragment, JOIN_GROUP_FRAGMENT_TAG);

    ft.addToBackStack("dummy");
    ft.commit();


    if (Build.VERSION.SDK_INT >= 21) {
        Log.i(TAG, "set enter transition");
        fragment.setEnterTransition(new Slide(Gravity.TOP));
        fragment.setExitTransition(new Slide(Gravity.BOTTOM));
    }

    ft.commit();
}

private void dismissFragment() {
    Fragment joinGroupFragment = getFragmentManager().findFragmentByTag(JOIN_GROUP_FRAGMENT_TAG);
    if (joinGroupFragment != null) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.replace(R.id.fragment_container, new Fragment());
        ft.remove(joinGroupFragment);
        ft.commit();
    }
}

这很好用并显示退出转换。但BackStackEntryCount尽管remove调用增加了已用内存,但仍在不断增加。

1 个答案:

答案 0 :(得分:0)

So it turns out that I do not understand FragmentManager's backstack yet. What I was trying to do could be done without backstack. It is simple.

For Transition, I need to replace the fragment with some other fragment, otherwise it is not a transition.

$(".ui-watermark").css("background-color", "red");

This is working well. I'll try it with backstack also and post later.