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

无内容变更时TransitionListener回调未触发问题咨询

解决ConstraintSet无变化时TransitionListener不回调的问题

哥们,你碰到的这个问题我之前也踩过坑——当ConstraintSet和当前布局完全一致的时候,TransitionManager会直接跳过动画流程,连带着你的TransitionListener回调也不会触发,确实挺闹心的。下面给你两个靠谱的解决思路:

思路1:提前判断布局差异,按需执行逻辑

这是最推荐的方案,先检查ConstraintSet和当前布局有没有差异,没差异就直接执行你原本要在onTransitionEnd里做的操作,不用走动画流程:

val transition = AutoTransition()
transition.addListener(object : Transition.TransitionListener {
    override fun onTransitionEnd(transition: Transition) {
        // 原本要执行的结束操作
        doSomething()
    }

    // 其他回调可以用空实现,嫌麻烦的话可以换成TransitionAdapter简化代码
    override fun onTransitionStart(transition: Transition) {}
    override fun onTransitionCancel(transition: Transition) {}
    override fun onTransitionPause(transition: Transition) {}
    override fun onTransitionResume(transition: Transition) {}
})

val constraintSet = ConstraintSet()
constraintSet.clone(this, R.layout.frame_loading)

// 关键:用matches()判断是否有布局变化
if (constraintSet.matches(rootLayout)) {
    // 没有布局变更,直接执行结束逻辑
    doSomething()
} else {
    // 有变化才启动动画
    TransitionManager.beginDelayedTransition(rootLayout, transition)
    constraintSet.applyTo(rootLayout)
}

思路2:强制触发Transition回调(hack式)

如果不管有没有布局变化,你都必须触发Transition的回调,可以给Transition添加一个空的过渡动画,确保系统认为有动画需要执行:

// 自定义一个包含空动画的TransitionSet,强制触发回调
val forcedTransition = TransitionSet()
    .addTransition(AutoTransition())
    .addTransition(object : Transition() {
        override fun captureStartValues(sceneValues: TransitionValues) {}
        override fun captureEndValues(sceneValues: TransitionValues) {}
        override fun createAnimator(sceneRoot: ViewGroup, startValues: TransitionValues?, endValues: TransitionValues?): Animator? {
            // 返回一个时长为0的空动画,确保流程走通
            return ValueAnimator.ofFloat(0f, 1f).apply { duration = 0 }
        }
    })

forcedTransition.addListener(object : Transition.TransitionListener {
    override fun onTransitionEnd(transition: Transition) {
        doSomething()
    }

    // 其他空实现...
    override fun onTransitionStart(transition: Transition) {}
    override fun onTransitionCancel(transition: Transition) {}
    override fun onTransitionPause(transition: Transition) {}
    override fun onTransitionResume(transition: Transition) {}
})

val constraintSet = ConstraintSet()
constraintSet.clone(this, R.layout.frame_loading)

TransitionManager.beginDelayedTransition(rootLayout, forcedTransition)
constraintSet.applyTo(rootLayout)

小提示

  • 思路1更高效,避免了不必要的动画开销,优先用这个;
  • 思路2适合一些特殊场景,但会多走一次空动画的流程,性能上略逊一筹。

内容的提问来源于stack exchange,提问作者Longi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:28:51