gpt4 book ai didi

android - 嵌套 fragment 在过渡动画期间消失

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:27:35 26 4
gpt4 key购买 nike

场景如下:Activity 包含 fragment A,它又使用 getChildFragmentManager() 添加 fragment A1A2 在其 onCreate 中,如下所示:

getChildFragmentManager()
.beginTransaction()
.replace(R.id.fragmentOneHolder, new FragmentA1())
.replace(R.id.fragmentTwoHolder, new FragmentA2())
.commit()

到目前为止,还不错,一切都按预期运行。

然后我们在 Activity 中运行以下事务:

getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(anim1, anim2, anim1, anim2)
.replace(R.id.fragmentHolder, new FragmentB())
.addToBackStack(null)
.commit()

在过渡期间, fragment Benter 动画运行正常,但 fragment A1 和 A2 完全消失。当我们使用返回按钮恢复事务时,它们会正确初始化并在 popEnter 动画期间正常显示。

在我的简短测试中,它变得更奇怪了——如果我为子 fragment 设置动画(见下文),当我们添加 fragment B 时,exit 动画会间歇运行

getChildFragmentManager()
.beginTransaction()
.setCustomAnimations(enter, exit)
.replace(R.id.fragmentOneHolder, new FragmentA1())
.replace(R.id.fragmentTwoHolder, new FragmentA2())
.commit()

我想要实现的效果很简单——我想要exit(或者应该是popExit?) fragment A上的动画( anim2) 运行,动画整个容器,包括其嵌套的 child 。

有什么办法可以实现吗?

编辑:请找一个测试用例here

Edit2:感谢@StevenByle 插入我继续尝试静态动画。显然你可以在每个操作的基础上设置动画(不是全局的整个事务),这意味着 child 可以有一个不确定的静态动画集,而他们的 parent 可以有不同的动画并且整个事情可以在一个事务中提交.请参阅下面的讨论和 updated test case project .

最佳答案

所以似乎有很多不同的解决方法,但基于@Jayd16 的回答,我认为我已经找到了一个非常可靠的万能解决方案,它仍然允许在子 fragment 上自定义过渡动画,并且不不需要对布局进行位图缓存。

有一个扩展 FragmentBaseFragment 类,并使您的所有 fragment 都扩展该类(不仅仅是子 fragment )。

BaseFragment 类中,添加以下内容:

// Arbitrary value; set it to some reasonable default
private static final int DEFAULT_CHILD_ANIMATION_DURATION = 250;

@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
final Fragment parent = getParentFragment();

// Apply the workaround only if this is a child fragment, and the parent
// is being removed.
if (!enter && parent != null && parent.isRemoving()) {
// This is a workaround for the bug where child fragments disappear when
// the parent is removed (as all children are first removed from the parent)
// See https://code.google.com/p/android/issues/detail?id=55228
Animation doNothingAnim = new AlphaAnimation(1, 1);
doNothingAnim.setDuration(getNextAnimationDuration(parent, DEFAULT_CHILD_ANIMATION_DURATION));
return doNothingAnim;
} else {
return super.onCreateAnimation(transit, enter, nextAnim);
}
}

private static long getNextAnimationDuration(Fragment fragment, long defValue) {
try {
// Attempt to get the resource ID of the next animation that
// will be applied to the given fragment.
Field nextAnimField = Fragment.class.getDeclaredField("mNextAnim");
nextAnimField.setAccessible(true);
int nextAnimResource = nextAnimField.getInt(fragment);
Animation nextAnim = AnimationUtils.loadAnimation(fragment.getActivity(), nextAnimResource);

// ...and if it can be loaded, return that animation's duration
return (nextAnim == null) ? defValue : nextAnim.getDuration();
} catch (NoSuchFieldException|IllegalAccessException|Resources.NotFoundException ex) {
Log.w(TAG, "Unable to load next animation from parent.", ex);
return defValue;
}
}

不幸的是,它确实需要反射(reflection);但是,由于此变通方法适用于支持库,因此除非您更新支持库,否则您不会冒底层实现发生变化的风险。如果您从源代码构建支持库,则可以将下一个动画资源 ID 的访问器添加到 Fragment.java 并消除反射的需要。

此解决方案消除了“猜测”父级动画持续时间的需要(这样“什么都不做”动画将具有与父级退出动画相同的持续时间),并允许您仍然对子 fragment 执行自定义动画(例如如果你用不同的动画交换子 fragment )。

关于android - 嵌套 fragment 在过渡动画期间消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16666397/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com