屏幕旋转后如何保留Activity执行动画后的状态?
解决Android动画后屏幕旋转状态丢失的问题
我完全懂你遇到的困扰——用ObjectAnimator做了按钮的透明、位移动画,结果一转屏幕,Activity重建,按钮又回到动画前的样子了对吧?其实问题的核心是:动画只是临时修改了视图的视觉表现,并没有真正改变视图的属性值,所以重建后系统会按照布局文件的初始配置来渲染视图。
用动画监听器在动画结束时同步真实属性是非常正确的思路,我给你分场景写具体代码,再补上屏幕旋转时的状态保存逻辑:
1. Alpha透明动画的处理
当你把按钮的alpha动画到0时,动画结束后要手动把按钮的真实alpha属性设为0,这样重建时就能保持透明状态:
// 创建alpha动画:从完全显示到完全透明 ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(yourButton, "alpha", 1f, 0f); alphaAnimator.setDuration(500); // 动画时长500ms // 添加动画监听器,同步真实属性 alphaAnimator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationEnd(Animator animation) { // 动画结束,把按钮的真实alpha属性设为0 yourButton.setAlpha(0f); } @Override public void onAnimationCancel(Animator animation) { // 动画被取消时也要同步,避免状态不一致 yourButton.setAlpha(0f); } @Override public void onAnimationRepeat(Animator animation) {} }); alphaAnimator.start();
2. ConstraintLayout中按钮上移100像素的处理
如果是通过translationY实现位移(这种方式简单直接),同样要在动画结束时同步真实的translationY属性:
// 上移100像素:因为Android的Y轴向下为正,所以用负数表示上移 ObjectAnimator moveAnimator = ObjectAnimator.ofFloat(yourButton, "translationY", 0f, -100f); moveAnimator.setDuration(500); moveAnimator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationEnd(Animator animation) { // 同步真实的translationY属性 yourButton.setTranslationY(-100f); } @Override public void onAnimationCancel(Animator animation) { yourButton.setTranslationY(-100f); } @Override public void onAnimationRepeat(Animator animation) {} }); moveAnimator.start();
如果是通过修改ConstraintLayout的约束(比如调整top margin)来实现位移,那动画结束后要确保约束已经被永久修改:
ConstraintLayout constraintLayout = findViewById(R.id.your_constraint_layout); ConstraintSet constraintSet = new ConstraintSet(); constraintSet.clone(constraintLayout); // 计算上移后的top margin:原margin减去100像素(注意如果是dp要转成px) int newTopMargin = constraintSet.getMargin(R.id.your_button, ConstraintSet.TOP) - 100; constraintSet.setMargin(R.id.your_button, ConstraintSet.TOP, newTopMargin); // 用Transition实现平滑动画,同时直接修改真实约束 Transition transition = new AutoTransition(); transition.setDuration(500); TransitionManager.beginDelayedTransition(constraintLayout, transition); constraintSet.applyTo(constraintLayout);
3. 关键:屏幕旋转时保存与恢复状态
光同步属性还不够,因为屏幕旋转时Activity会重建,所以需要把这些属性值保存下来,在重建时恢复:
保存状态(重写onSaveInstanceState)
@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // 保存按钮的alpha值 outState.putFloat("button_alpha", yourButton.getAlpha()); // 保存位移的translationY值 outState.putFloat("button_transY", yourButton.getTranslationY()); // 如果是修改约束的margin,保存margin值 ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) yourButton.getLayoutParams(); outState.putInt("button_top_margin", params.topMargin); }
恢复状态(在onCreate中处理)
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_layout); yourButton = findViewById(R.id.your_button); if (savedInstanceState != null) { // 恢复alpha状态 float alpha = savedInstanceState.getFloat("button_alpha", 1f); yourButton.setAlpha(alpha); // 恢复位移状态 float transY = savedInstanceState.getFloat("button_transY", 0f); yourButton.setTranslationY(transY); // 恢复约束margin状态 int topMargin = savedInstanceState.getInt("button_top_margin", 0); ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) yourButton.getLayoutParams(); params.topMargin = topMargin; yourButton.setLayoutParams(params); } }
这样一套操作下来,不管是alpha动画还是位移动画,屏幕旋转后按钮都会保持动画结束后的状态啦~
内容的提问来源于stack exchange,提问作者umbasa07
相关产品推荐
相关产品推荐

