Android动画withStartAction中View属性设置失效问题求助
解决ViewPropertyAnimator中withStartAction设置的属性不生效问题
嘿,这个坑我之前踩过!你猜的没错,问题确实出在.scaleX(1)这个调用上,我来给你掰扯清楚原因,再给你几个可行的解决方案~
为什么会出现这个问题?
Android的ViewPropertyAnimator有个容易忽略的细节:当你调用像.scaleX(targetValue)这类单个属性的动画方法时,它会立刻记录当前View的对应属性值作为动画的起始值,而withStartAction里的代码是在动画即将启动的瞬间才执行的。
也就是说,你调用.scaleX(1)的时候,框架已经把当时的scaleX值记为动画起始值了,等withStartAction里设置v.setScaleX(0.8f)的时候,起始值已经固定,动画还是会从之前记录的值跑到1,自然就覆盖了你手动设置的初始值。而scaleY因为后面没调用.scaleY()方法,框架没自动生成对应的动画,所以你在withStartAction里设置的1.5f就能正常保留。
解决方案1:明确指定动画的起始和结束值
如果你还想用ViewPropertyAnimator,可以用带起始值的重载方法,直接告诉框架动画的起始和结束值,这样就不会被自动记录的初始值覆盖了:
v.animate() .withStartAction(new Runnable() { @Override public void run() { v.setScaleX(0.8f); v.setScaleY(1.5f); } }) // 明确指定scaleX从0.8f动画到1f,代替原来的scaleX(1) .scaleX(0.8f, 1f) .withEndAction(new Runnable() { @Override public void run() { v.setScaleX(0.3f); } }) .setDuration(500) .start();
或者用相对变化的scaleXBy,因为0.8f到1f是增加了0.2f,所以也可以写成:
.scaleXBy(0.2f)
解决方案2:换用AnimatorSet更灵活控制
如果你的动画逻辑更复杂,AnimatorSet会是更靠谱的选择,它能让你完全掌控初始状态、动画顺序和结束动作:
// 先手动设置初始缩放状态 v.setScaleX(0.8f); v.setScaleY(1.5f); // 创建scaleX到1的动画 ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(v, "scaleX", 1f); scaleXAnim.setDuration(500); // 添加动画结束后的动作 scaleXAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { v.setScaleX(0.3f); } }); // 启动动画 scaleXAnim.start();
这种方式逻辑更清晰,也不容易出现属性被覆盖的问题。
内容的提问来源于stack exchange,提问作者IC ice




