属性动画实现View的宽高改变

属性动画实现View的宽高改变

问题

下面是对Button宽度执行动画的代码

public void click(View view) {
    /*
    *. 直接对View的宽度进行动画
    */
    ObjectAnimator.ofInt(startBtn, "width", 400).setDuration(3000).start();
   
}

这种方式会发现Button的宽度执行动画后没有任何效果。原因是Button继承自TextView,TextView的setWidth()方法只是设置控件的最小宽度和最大宽度,故不会有任何效果。

解决办法

  1. 给你的对象要操作的属性加get()和set()方法(有源码才可以)
  2. 使用一个类封装原始对象,添加get()和set()方法即可
  3. 使用ValueAnimator,监听动画过程,自己实现属性值得改变

具体实现

1和2方式思路相同,只在于是否直接在源码添加get和set方法区别

public void click(View view) {
    /*
    * 通过封装类添加get/set方法来进行View真正宽度的改变
    */
    ViewWrapper viewWrapper = new ViewWrapper(startBtn);
    ObjectAnimator.ofInt(viewWrapper, "trueWidth", 400).setDuration(3000).start();
   
}

private static class ViewWrapper {
    private View mTarget;

    public ViewWrapper(View view) {
        mTarget = view;
    }

    public void setTrueWidth(int width) {
        mTarget.getLayoutParams().width = width;
        mTarget.requestLayout();//必须调用,否则宽度改变但UI没有刷新
    }

    public int getTrueWidth() {
        return mTarget.getLayoutParams().width;
    }
}

3 使用ValueAnimator
下面的动画通过ValueAnimator实现Button宽度改变

ValueAnimator valueAnimator = ValueAnimator.ofInt(100, 50, 200, 100).setDuration(5000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        startBtn.getLayoutParams().width = (int) animation.getAnimatedValue();
        startBtn.requestLayout();
    }
});
valueAnimator.start();

首先通过ValueAnimator实现值5s内在100->50->200->100的一个变化,变化速率100fps,通过添加AnimatorUpdateListener监听器来监听值变化,每次值变化都会回调onAnimationUpdate()方法,再根据更新的值对控件的宽度进行改变,达到动画效果。