Material Container Transform+FAB切换Fragment动画不流畅问题求助
问题描述
点击Floating Action Button(FAB)使用Material Container Transform动画跳转至Fragment B时,FAB会短暂放大并保持可见,过渡效果不流畅,需优化动画或隐藏跳转时的FAB。
解决方案
1. 移除Fragment A的Hold退出过渡
你为Fragment A设置了exitTransition = Hold(),这会让Fragment A的视图在过渡期间持续可见,导致FAB与Fragment B的容器重叠显示。直接移除该设置,让系统使用默认过渡行为即可。
2. 精细化配置MaterialContainerTransform
在Fragment B中对MaterialContainerTransform做针对性配置,确保源视图(FAB)正确过渡、目标容器平滑显示:
- 设置透明遮罩避免干扰视觉
- 匹配Material Design标准动画时长
- 配置淡出模式让源视图自然消失
3. 修正共享元素ID匹配问题
检查Fragment A布局与代码中的FAB ID:布局中是create_btn,但代码里用了createTask,ID不匹配会导致共享元素动画异常,需保持一致。
修改后的代码
Fragment A 代码
class FragmentA : Fragment() { private var _binding: FragmentABinding? = null private val binding get() = _binding!! override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 移除Hold过渡,使用系统默认行为 } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentABinding.inflate(inflater) binding.create_btn.setOnClickListener { val extras = FragmentNavigatorExtras(binding.create_btn to "my_transition") findNavController().navigate(R.id.action_FragmentA_to_FragmentB,null,null,extras) } return binding.root } override fun onDestroyView() { super.onDestroyView() _binding = null } }
Fragment B 代码
class FragmentB : Fragment() { private var _binding: FragmentBBinding? = null private val binding get() = _binding!! override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) sharedElementEnterTransition = MaterialContainerTransform().apply { duration = 300L // Material标准动画时长 scrimColor = Color.TRANSPARENT // 移除过渡遮罩 fadeMode = MaterialContainerTransform.FADE_MODE_OUT // 源视图淡出 setAllContainerColors(requireContext().getColor(R.color.background)) // 匹配页面背景色 } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentBBinding.inflate(inflater) return binding.root } override fun onDestroyView() { super.onDestroyView() _binding = null } }
额外优化:手动控制FAB可见性
若上述调整后仍有视觉冲突,可在跳转时立即隐藏FAB,返回时恢复:
在Fragment A的点击事件中添加:
binding.create_btn.setOnClickListener { binding.create_btn.visibility = View.INVISIBLE val extras = FragmentNavigatorExtras(binding.create_btn to "my_transition") findNavController().navigate(R.id.action_FragmentA_to_FragmentB,null,null,extras) }
在Fragment A的onViewCreated中恢复可见:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.create_btn.visibility = View.VISIBLE }
内容的提问来源于stack exchange,提问作者REX
相关产品推荐
相关产品推荐

