You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动