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
相关产品推荐
相关产品推荐

