上回书说到Android动画的分类以及基本使用,这会书主要说Android属性动画的原理,对于View动画的原理本篇不做深入分析。对于Android动画的基础请看深入分析Android动画(一)
我们先来看一个需求:要求对一个Button做动画,要求让其宽度从原始宽度增加到500px。这也太简单了,于是我们的主人公鸣人不假思索的写下了如下的代码
1 Button mButton = (Button) findViewById(R.id.button);
2 ObjectAnimator.ofInt(mButton,"width",500).setDuration(1000).start();
程序正常运行,借下来鸣人就分析了上述代码实现的原理,通过研究鸣人惊奇的发现了以下规则:
以上的条件缺一不可
这时鸣人又想到一个问题如果想要对一个对象的属性做动画,但是属性又没有对应的get和set方法怎么办呢??
通过研究发现有如下三种解决办法:
对于方法2和方法3下面给出例子,仍以上面Button的宽度动画作为需求
方法2:
1 mButton = (Button) findViewById(R.id.button);
2 ObjectAnimator.ofInt(new ViewWrapper(mButton),"width",500).setDuration(1000).start();
3
4 private class ViewWrapper{
5 private View mTarget;
6
7 public ViewWrapper(View mTarget) {
8 this.mTarget = mTarget;
9 }
10
11
12 public int getWidth() {
13 return mTarget.getLayoutParams().width;
14 }
15
16 public void setWidth(int width) {
17 mTarget.getLayoutParams().width = width;
18 mTarget.requestLayout();
19 }
20 }
方法3:
1 mButton = (Button) findViewById(R.id.button);
2 performAnimate(mButton, mButton.getWidth(), 500);
3
4
5
6 private void performAnimate(final View target, final int start, final int end) {
7
8 ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100);
9 valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
10
11 // 持有一个IntEvaluator对象,方便下面估值的时候使用
12 private IntEvaluator mEvaluator = new IntEvaluator();
13
14 @Override
15 public void onAnimationUpdate(ValueAnimator animator) {
16 // 获得当前动画的进度值,整型,1-100之间
17 int currentValue = (Integer) animator.getAnimatedValue();
18 Log.d(TAG, "current value: " + currentValue);
19
20 // 获得当前进度占整个动画过程的比例,浮点型,0-1之间
21 float fraction = animator.getAnimatedFraction();
22 // 直接调用整型估值器通过比例计算出宽度,然后再设给Button
23 target.getLayoutParams().width = mEvaluator.evaluate(fraction, start, end);
24 target.requestLayout();
25 }
26 });
27
28 valueAnimator.setDuration(5000).start();
29 }