You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 10:40:59