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

Android TransitionDrawable重复调用startTransition闪烁如何解决

问题根因

闪烁完全是TransitionDrawable的调用逻辑缺失状态校验导致的:

  • 你当前的实现里,不管灯泡当前是亮是灭,只要轮询拿到结果就直接调用过渡方法
  • startTransition()的固定逻辑是永远以第一层drawable(关灯图)为起点,向第二层drawable(开灯图)执行过渡:哪怕当前已经完全显示开灯状态,调用该方法会瞬间重置回关灯状态再启动过渡,即使传入0时长,也会触发两次drawable切换(先切关灯、再切开灯),带来帧级别的闪动
  • reverseTransition()逻辑同理,重复调用同状态的过渡方法,必然会触发无意义的drawable重置,表现就是类似坏荧光灯的闪烁。
修复步骤
  • 新增成员变量维护当前灯泡的显示状态,仅当目标状态和当前状态不一致时才执行过渡
  • 初始化时对齐状态标记和drawable的初始显示层级,避免初始状态错位
  • (可选)增加网络请求时序校验,避免旧请求返回覆盖最新状态

核心代码修改

首先新增状态标记,改造ImageClick方法:

// 新增成员变量,和初始drawable状态保持一致,默认关灯
private boolean isBulbOn = false;

private void ImageClick(boolean b) {
    final ImageView image = (ImageView) findViewById(R.id.image);
    TransitionDrawable drawable = (TransitionDrawable) image.getDrawable();
    // 目标状态和当前状态一致,直接返回,不做任何drawable操作
    if (isBulbOn == b) {
        return;
    }
    if (b) {
        drawable.startTransition(1000); // 开灯过渡
    } else {
        drawable.reverseTransition(1000); // 关灯过渡
    }
    // 状态更新
    isBulbOn = b;
}

在Activity初始化逻辑中对齐drawable初始状态:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_device);
    ImageView image = findViewById(R.id.image);
    // 如果布局中已经直接给ImageView设置了transition资源,以下初始化代码可省略
    TransitionDrawable bulbTransition = (TransitionDrawable) ContextCompat.getDrawable(this, R.drawable.bulb_transition);
    image.setImageDrawable(bulbTransition);
    // 重置到初始关灯状态,和isBulbOn默认值对齐
    bulbTransition.resetTransition();
}

注意事项

不要尝试通过drawable.getCurrent()判断当前显示层级来替代自定义状态标记:TransitionDrawable在过渡过程中返回的current是动态生成的过渡态drawable,判断逻辑不可靠,自行维护布尔状态标记是成本最低、稳定性最高的方案。

如果你的网络环境存在请求乱序问题(比如先发的请求后返回),可以给每个请求加自增序号,仅处理最新序号请求返回的状态,避免旧结果错误覆盖当前灯泡状态。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:24:23