@@ -57,6 +57,7 @@ Android动画
5757 ```
5858
59596. Frame 动画
60+ 在`SDK `中提到,不要在`onCreate`中调用`start`方法开始播放`Frame `动画,因为`AnimationDrawable `还没有完全跟`Window `相关联,如果想要界面显示时就开始播放帧动画的话,可以在`onWindowFocusChanged()`中调用`start()`。
6061
6162 - 在`drawable`目录下新建一个`xml`文件,内容如下:
6263
@@ -101,7 +102,200 @@ Android动画
101102 CycleInterpolator // 曲线运动特效,要传递float型的参数。
102103 animation. setInterpolator(new LinearInterpolator ());// 指定动画的运行效果
103104 ```
105+
106+ 上面所讲的动画都是`Android 3.0 `之前的动画,也就是我们最先熟悉的`Frame `动画和`Tween `动画。
107+
108+ 从`3.0 `开始又引入了一个新的动画叫做`Property `动画。并且针对这三种动画的动画模式分为:
109+
110+ - `Property Animation ` : 属性动画,从`Android 3.0 `开始引进,更改的是对象的实际属性,而且属性动画不止可以应用于`View `还可以应用于任何对象。
111+ - `View Animation ` : 指之前的`Tween `动画,`alpha scale translate rotate`等。为什么叫做`View Animation `呢?因为它只能应用于`View `对象,而且只支持一部分属性,如支持缩放旋转而不支持背景颜色的变化。对于`View Animation `而言,它只改变了`View `对象绘制的位置,而没有改变`View `对象本身的属性,比如,有一个200 * 200 大小的`Button `,你用`Tween `动画给放大到500 * 500 但是它的有效点击区域还是200 * 200 。
112+ - `Drawable Animation ` : 指之前的`Frame `动画。因为它是通过一帧帧的图片来播放的。
104113
114+ 下面我们开始仔细讲解一下`Property Animation `
115+ -- -
116+
117+ 官方文档中是这样这样介绍属性动画的:
118+
119+ ```
120+ The property animation system is a robust framework that allows you to animate almost anything. You can define an animation to change any object property over time, regardless of whether it draws to the screen or not. A property animation changes a property's (a field in an object) value over a specified length of time. To animate something, you specify the object property that you want to animate, such as an object's position on the screen, how long you want to animate it for, and what values you want to animate between.
121+ ```
122+ 一个强大的框架。
123+
124+ 在`Property Animation`中,可以对动画应用以下属性:
125+
126+ - `Duration`: 指定动画持续时间,默认时间是`300ms`
127+ - `TimeInterpolation`: 一些效果,如加速、加速等。
128+ - `Repeat count and behavior `: 重复次数已经
129+ - `Animation Set`: 动画合集。用来同时或者顺序播放多个动画。
130+ - `Frame Refresh Delay`: 多长时间刷新一次,默认是`10ms`。
131+
132+ ###`ValueAnimator`
133+
134+
135+ `ValueAnimator`包含`Property Animation`动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等。应用`Property Animation`有两个步聚:
136+
137+ - 计算属性值
138+ - 根据属性值执行相应的动作,如改变对象的某一属性。
139+
140+ `ValuAnimiator`只完成了第一步工作,如果要完成第二步,需要实现`ValueAnimator.onUpdateListener`接口,这个接口只有一个函数`onAnimationUpdate()`,在这个函数中会传入`ValueAnimator`对象做为参数,通过这个`ValueAnimator`对象的`getAnimatedValue()`函数可以得到当前的属性值。
141+
142+ ###`ObjectAnimator`
143+
144+ 继承自`ValueAnimator`,要指定一个对象及该对象的一个属性,当属性值计算完成时自动设置为该对象的相应属性,即完成了`Property Animation`的全部两步操作。实际应用中一般都会用`ObjectAnimator`来改变某一对象的某一属性,但用`ObjectAnimator`有一定的限制,要想使用`ObjectAnimator`,应该满足以下条件:
145+
146+ - 对象应该有一个`setter`函数:`set<PropertyName>`(驼峰命名法)
147+ - 如上面的例子中,像`ofFloat`之类的工场方法,第一个参数为对象名,第二个为属性名,后面的参数为可变参数,如果`values…`参数只设置了一个值的话,那么会假定为目的值,属性值的变化范围为当前值到目的值,为了获得当前值,该对象要有相应属性的`getter`方法:`get<PropertyName>`
148+ - 如果有`getter`方法,其应返回值类型应与相应的`setter`方法的参数类型一致。
149+ - `object`的`setXxx`对属性`xxx`所做的改变必须能够通过某种方法反映出来,比如会带来`ui`的改变啥的(如果这条不满足,动画无效果),例如我对`TextView`或者`Button`使用`width`的`ObjectAnimator`动画,就会发现无效,虽然他们都有`setWidth`和`getWidth`方法,但是`setWidth`方法的内部实现是改变`TextView`的最大宽度和最小宽度的,和`TextView`的宽度不是一个东西。所以动画就会无效。确切的说`TextView`的宽度对应的是`xml`中`android:layout_width`属性,而`TextView`还有另外一个属性:`android:width`,而`android:width` 属性对应的就是`TextView`中的`setWidth`方法。
150+
151+ 如果上述条件不满足,则不能用`ObjectAnimator`,应用`ValueAnimator`代替。
152+ 也就是说`ObjectAnimator`内部的工作机制是通过寻找特定属性的`get`和`set`方法,然后通过方法不断地对值进行改变,从而实现动画效果的。
153+
154+ ###`AnimationSet`
155+
156+
157+ `AnimationSet`提供了一个把多个动画组合成一个组合的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等。
158+
159+ 以下例子同时应用5个动画:
160+
161+ - 播放anim1;
162+ - 同时播放anim2,anim3,anim4;
163+ - 播放anim5。
164+
165+ ```java
166+ AnimatorSet bouncer = new AnimatorSet();
167+ bouncer.play(anim1).before(anim2);
168+ bouncer.play(anim2).with(anim3);
169+ bouncer.play(anim2).with(anim4)
170+ bouncer.play(anim5).after(amin2);
171+ animatorSet.start();
172+ ```
173+
174+ ###TypeEvalutors
175+
176+
177+ 根据属性的开始、结束值与` TimeInterpolation ` 计算出的比例值来计算当前时间对应的属性值,` Android ` 提供了一下几种` evalutor ` :
178+
179+ - ` IntEvalutor ` :` int ` 类型的属性值
180+ - ` FloatEvaluator ` :
181+ - ` ArgbEvaluator ` : 属性的值类型为十六进制颜色值;
182+ - ` TypeEvaluator ` : 一个接口,可以通过实现该接口自定义Evaluator。
183+ 自定义` TypeEvaluator ` 也很简单,只需要实现一个方法,如` FloatEvalutor ` 的定义:
184+ ``` java
185+ public class FloatEvaluator implements TypeEvaluator {
186+ public Object evaluate (float fraction , Object startValue , Object endValue ) {
187+ float startFloat = ((Number ) startValue). floatValue();
188+ return startFloat + fraction * (((Number ) endValue). floatValue() - startFloat);
189+ }
190+ }
191+ ```
192+ ` evaluate() ` 方法当中传入了三个参数,第一个参数` fraction ` 非常重要,这个参数用于表示动画的完成度的,我们应该根据它来计算当前动画的值应该是多少,第二第三个参数分别表示动画的初始值和结束值。那么上述代码的逻辑就比较清晰了,用结束值减去初始值,算出它们之间的差值,然后乘以` fraction ` 这个系数,再加上初始值,那么就得到当前动画的值了。
193+
194+
195+ ###` TimeInterplator `
196+ Time interplator定义了属性值变化的方式,如线性均匀改变,开始慢然后逐渐快等。在Property Animation中是TimeInterplator,在View Animation中是Interplator,这两个是一样的,在3.0之前只有Interplator,3.0之后实现代码转移至了TimeInterplator。Interplator继承自TimeInterplator,内部没有任何其他代码。
197+
198+ - AccelerateInterpolator 加速,开始时慢中间加速
199+ - DecelerateInterpolator 减速,开始时快然后减速
200+ - AccelerateDecelerateInterolator 先加速后减速,开始结束时慢,中间加速
201+ - AnticipateInterpolator 反向 ,先向相反方向改变一段再加速播放
202+ - AnticipateOvershootInterpolator 反向加回弹,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
203+ - BounceInterpolator 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
204+ - CycleIinterpolator 循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2 * mCycles * Math.PI * input)
205+ - LinearInterpolator 线性,线性均匀改变
206+ - OvershottInterpolator 回弹,最后超出目的值然后缓慢改变到目的值
207+ - TimeInterpolator 一个接口,允许你自定义interpolator,以上几个都是实现了这个接口
208+
209+
210+ ###` PropertyValuesHolder `
211+
212+ 如果要实现一个对象不同属性的动画效果,除了` Set ` ,我们还可以利用` PropertyValuesHolder ` 和` ViewPropertyAnimator ` 对象来实现,具体做法如下:
213+ ```
214+ PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
215+ PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
216+ ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
217+ ```
218+
219+ ###` ViewPropertyAnimator `
220+
221+ `* <p >This class is not constructed by the caller, but rather by the View whose properties
222+ * it will animate. Calls to {@link android.view.View#animate()} will return a reference
223+ * to the appropriate ViewPropertyAnimator object for that View.</p >`
224+
225+ 如果需要对一个View的多个属性进行动画可以用ViewPropertyAnimator类,该类对多属性动画进行了优化,会合并一些invalidate()来减少刷新视图,该类在3.1中引入。
226+
227+ ` view.animate() ` 方法会返回` ViewPropertyAnimator ` 类。
228+ ``` java
229+ myView. animate(). x(50f ). y(100f );
230+ ```
231+ 的效果与上面的` PropertyValuesHolder ` 例子中的效果完全一致。
232+ 但是你有没有发现我们自始至终没有调用过` start() ` 方法,这是因为新的接口中使用了隐式启动动画的功能,只要我们将动画定义完成之后,动画就会自动启动。并且这个机制对于组合动画也同样有效,只要我们不断地添加新的方法,那么动画就不会立刻执行,等到所有在` ViewPropertyAnimator ` 上设置的方法都执行完毕后,动画就会自动启动。当然如果不想使用这一默认机制的话,我们也可以显式地调用` start() ` 方法来启动动画。
233+
234+
235+
236+ ###XML中定义
237+
238+ 在` res/animator ` 中定义对应的动画` xml `
239+ - <animator > 对应代码中的ValueAnimator
240+ - <objectAnimator > 对应代码中的ObjectAnimator
241+ - <set > 对应代码中的AnimatorSet
242+ 例如:
243+
244+ ``` xml
245+ <?xml version =" 1.0" encoding =" utf-8" ?>
246+ <objectAnimator
247+ xmlns : android =" http://schemas.android.com/apk/res/android"
248+ android : propertyName =" scaleX"
249+ android : duration =" 2000"
250+ android : valueFrom =" 1.0"
251+ android : valueTo =" 2.0"
252+ android : valueType =" floatType"
253+ android : repeatCount =" 1"
254+ android : repeatMode =" reverse" >
255+ </objectAnimator >
256+ ```
257+ 这里说明一下` valueFrom ` 和` valueTo ` :是动画开始和结束值,如果我们缩放,则它们对应的是倍数,如果我们平移则对应的就是距离了。
258+
259+ 接下来就是调用了
260+ ``` java
261+ scaleXAnimator = (ObjectAnimator )AnimatorInflater . loadAnimator(this , R . animator. scalex);
262+ scaleXAnimator. setTarget(btnScaleX);
263+ scaleXAnimator. start();
264+ ```
265+
266+ 那如果我们要播放多个动画怎么办?
267+ ``` xml
268+ <?xml version =" 1.0" encoding =" utf-8" ?>
269+ <set xmlns : android =" http://schemas.android.com/apk/res/android"
270+ android : ordering =" together" >
271+ <objectAnimator
272+ android : duration =" 2000"
273+ android : propertyName =" scaleX"
274+ android : repeatCount =" 1"
275+ android : repeatMode =" reverse"
276+ android : valueFrom =" 1.0"
277+ android : valueTo =" 2.0" >
278+ </objectAnimator >
279+ <objectAnimator
280+ android : duration =" 2000"
281+ android : propertyName =" scaleY"
282+ android : repeatCount =" 1"
283+ android : repeatMode =" reverse"
284+ android : valueFrom =" 1.0"
285+ android : valueTo =" 2.0" >
286+ </objectAnimator >
287+ </set >
288+ ```
289+ ``` java
290+ animatorScaleSet = (AnimatorSet )AnimatorInflater . loadAnimator(this , R . animator. scale);
291+ animatorScaleSet. setTarget(btnScale);
292+ animatorScaleSet. start();
293+
294+ ```
295+
296+
297+
298+
105299---
106300
107301- 邮箱 :charon.chui@gmail.com
0 commit comments