使用 setExitTransition 到 Fragment 时出现 NullPointerException
NullPointerException when using setExitTransition to Fragment
我正在尝试为片段的进入和退出设置动画。 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: Attempt to read from field 'int
android.app.Fragment.mContainerId' on a null object reference
at android.app.BackStackRecord.onPreDraw(BackStackRecord.java:1131)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1970)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at 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();
}
}
我知道后台堆栈中没有任何用于转换的片段,但添加虚拟片段也无济于事。有什么解决方法吗?
更新
我使用了相同的片段,而不是虚拟片段。
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()
记录 backstack 计数,删除片段时它显示 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
调用增加了使用的内存。
原来我还不了解FragmentManager的backstack。我想做的事情可以在没有 backstack 的情况下完成。很简单。
对于过渡,我需要用其他片段替换片段,否则它不是过渡。
private void showFragment() {
Fragment fragment = JoinGroupFragment.newInstance();
FragmentTransaction ft = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, fragment, JOIN_GROUP_FRAGMENT_TAG);
ft.commit();
if (Build.VERSION.SDK_INT >= 21) {
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.commit();
}
}
效果很好。我也会用 backstack 尝试它,稍后 post。
我正在尝试为片段的进入和退出设置动画。 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: Attempt to read from field 'int android.app.Fragment.mContainerId' on a null object reference at android.app.BackStackRecord.onPreDraw(BackStackRecord.java:1131) at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1970) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) at android.view.Choreographer.doCallbacks(Choreographer.java:580) at android.view.Choreographer.doFrame(Choreographer.java:550) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5254) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) at 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();
}
}
我知道后台堆栈中没有任何用于转换的片段,但添加虚拟片段也无济于事。有什么解决方法吗?
更新
我使用了相同的片段,而不是虚拟片段。
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()
记录 backstack 计数,删除片段时它显示 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
调用增加了使用的内存。
原来我还不了解FragmentManager的backstack。我想做的事情可以在没有 backstack 的情况下完成。很简单。
对于过渡,我需要用其他片段替换片段,否则它不是过渡。
private void showFragment() {
Fragment fragment = JoinGroupFragment.newInstance();
FragmentTransaction ft = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, fragment, JOIN_GROUP_FRAGMENT_TAG);
ft.commit();
if (Build.VERSION.SDK_INT >= 21) {
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.commit();
}
}
效果很好。我也会用 backstack 尝试它,稍后 post。