共享元素转换替换了片段,因此我无法将其添加到后退堆栈并在按下后退箭头按钮时调用 popbackstack。
我有一个主要活动,里面有一个主要片段。主片段处理表格布局,因此每个选项卡都是一个带有回收器视图的片段。单击回收器视图元素时,共享元素转换开始到显示元素详细信息的新片段。
这是适配器,单击元素的位置:
holder.image.setTransitionName("transition" + holder.getAdapterPosition());
if (fragment instanceof tab1_anime) {
((tab1_anime) fragment).openShowElementFragment(holder.getAdapterPosition(), v.findViewById(R.id.main_image));
}
这是我的选项卡片段中的 openShowElementFragment:
public void openShowElementFragment(int position, View view) {
AddElement element = anime_list.get(position);
ShowElementFragment showElementFragment = new ShowElementFragment();
Bundle bundle = new Bundle();
bundle.putString("transitionName", "transition" + position);
bundle.putSerializable("element", element);
bundle.putInt("position", position);
bundle.putInt("from", 0);
showElementFragment.setArguments(bundle);
((MainActivity) context).showFragmentWithTransition(this, showElementFragment, "showElementFragment", view, "transition" + position);
}
这是前面代码块中调用的 openshowelementfragment 函数:
public void showFragmentWithTransition(Fragment current, Fragment newFragment, String tag, View sharedView, String sharedElementName) {
FragmentManager fragmentManager = getSupportFragmentManager();
// check if the fragment is in back stack
boolean fragmentPopped = fragmentManager.popBackStackImmediate(tag, 0);
if (fragmentPopped) {
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
current.setSharedElementReturnTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
current.setExitTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
newFragment.setSharedElementEnterTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
newFragment.setEnterTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
}
fragmentManager.beginTransaction()
.replace(R.id.fragmentHolder, newFragment)
.addToBackStack(null)
.addSharedElement(sharedView, sharedElementName)
.commit();
}
}
这是后退箭头按钮:
back_arrow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getSupportFragmentManager().popBackStack();
}
});
如果我尝试添加新片段而不是替换旧片段,则根本没有任何动画。
如果我尝试用新片段替换旧片段并使用 addtobackstack(null) ,那么共享元素转换会从头到尾工作但是最后的片段没有数据,为空:
我也尝试过:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragmentHolder, new MainFragment())
.addToBackStack(null)
.commit();
但是这样,共享元素转换在退出时不起作用:
我认为你的问题与退出转换有关,因为你得到了空列表的解决方案,现在检查下面的代码退出转换效果。
public void showFragmentWithTransition(Fragment current, Fragment newFragment, String tag, View sharedView, String sharedElementName) {
FragmentManager fragmentManager = getSupportFragmentManager();
// check if the fragment is in back stack
boolean fragmentPopped = fragmentManager.popBackStackImmediate(tag, 0);
if (fragmentPopped) {
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
current.setSharedElementReturnTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
current.setExitTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
newFragment.setSharedElementEnterTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
newFragment.setEnterTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
newFragment.setExitTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
newFragment.setSharedElementReturnTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
}
getSupportFragmentManager().beginTransaction()
.addSharedElement(sharedElement, transitionName)
.replace(R.id.container, newFragment)
.addToBackStack(null)
.commit();
}
}
这里我添加了两条新行用于退出转换。
newFragment.setExitTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition)); newFragment.setSharedElementReturnTransition(TransitionInflater.from(this).inflateTransition(R.transition.default_transition));
如果它不起作用,请点击以下链接,我认为这会对您有所帮助。 https://medium.com/@bherbst/fragment-transitions-with-shared-elements-7c7d71d31cbb
你所谓的
sharedElementName
其实是一个transitionName
。
a) 参考示例不直接操作返回堆栈:
Android 片段转换:RecyclerView 到 ViewPager 和 博客。
b) 手动事务可能需要另一种方法调用顺序:
getSupportFragmentManager().beginTransaction()
.addSharedElement(sharedElement, transitionName)
.replace(R.id.container, newFragment)
.addToBackStack(null)
.commit();
另请参阅此示例,如何设置替代过渡,相比之下:
TransitionInflater.from(this).inflateTransition(R.transition.default_transition)
无论
R.transition.default_transition
可能是什么。
当两种方式使用相同的转换而不是进入/退出转换时,可能看起来很奇怪,就像
NavAction
一样。使用导航组件时,FragmentNavigator.Extras
可用于应用进入/退出转换;这也可以与ActionBar
结合使用。选项 a) 可能不太复杂。 b) 类似的 this Kotlin 示例可能更有意义。
当支持“开箱即用”的进入/退出转换时,构建笨重的导航 FX 是毫无意义的。加载图像时,也许可以考虑使用 Glide 来加载。
假设如下 build.gradle
;无需重新发明轮子。
dependencies {
androidTestImplementation "androidx.navigation:navigation-testing:2.5.3"
implementation 'androidx.navigation:navigation-runtime:2.5.3'
implementation 'androidx.navigation:navigation-fragment:2.5.3'
implementation 'androidx.navigation:navigation-ui:2.5.3'
annotationProcessor 'com.github.bumptech.glide:compiler:4.14.2'
implementation 'com.github.bumptech.glide:glide:4.14.2'
}
那么
Navigation
和
FragmentNavigator.Extras
可能是当前的方法:Bundle navArgs = new Bundle();
navArgs.putInt("position", position);
FragmentNavigator.Extras extras = new FragmentNavigator.Extras.Builder()
.addSharedElement(sharedElement, transitionName)
.build();
Navigation.findNavController(view).navigate(
R.id.details, // ID of Nav destination
navArgs, // Bundle of args
null, // NavOptions
extras);
还可以在 XML
<action/>
节点中定义transitionName。