屏幕旋转时ProgressBar使用ObjectAnimator的进度动画卡住无法重置问题
问题根本原因
- 屏幕旋转时Android默认会销毁重建Activity,系统会自动保存所有带ID的View的状态,ProgressBar的
progress值会被存储,并且在onRestoreInstanceState阶段(执行时机晚于onCreate)自动恢复到销毁前的数值,你在onCreate中调用的setProgress(100)会被这个系统自动恢复操作覆盖,所以不生效。 - 你声明的
ObjectAnimator是方法局部变量,旧Activity销毁前如果没有主动取消动画,会和新实例的动画、View状态产生冲突,进一步导致进度显示异常。
解决方法
方案1:禁止旋转时重建Activity(无需改业务逻辑,适配简单)
如果你的应用横竖屏布局一致,直接在AndroidManifest.xml对应的Activity标签中添加配置即可:
<activity android:name=".MainActivity" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden" />
添加后旋转屏幕不会触发Activity销毁重建,动画不会中断,进度也不会卡住。
方案2:主动处理状态恢复,兼容横竖屏不同布局
如果需要适配横竖屏不同布局,修改代码如下:
- 将动画实例改为Activity成员变量,方便生命周期管理
- 在
onPause/onDestroy阶段主动取消动画 - 可以在
onPostCreate(系统恢复完View状态之后才会调用)阶段设置进度、启动动画,避免被系统状态恢复覆盖
示例代码:
private ObjectAnimator progressAnimator; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); } @Override protected void onPostCreate(@Nullable Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); ProgressBar hintProgressBar = findViewById(R.id.hint_progress_bar); // 第二个参数传false表示直接设置进度,不要过渡动画,避免残留 hintProgressBar.setProgress(100, false); animateProgress(hintProgressBar); } private void animateProgress(ProgressBar progressBar) { // 先取消已经存在的动画,避免冲突 if (progressAnimator != null && progressAnimator.isRunning()) { progressAnimator.cancel(); } progressAnimator = ObjectAnimator.ofInt(progressBar, "progress", 0, 100); progressAnimator.setDuration(5000); progressAnimator.setInterpolator(new LinearInterpolator()); progressAnimator.start(); } @Override protected void onDestroy() { super.onDestroy(); if (progressAnimator != null) { progressAnimator.cancel(); progressAnimator = null; } }
内容的提问来源于stack exchange,提问作者AtomicallyBeyond
相关产品推荐
相关产品推荐

