android動(dòng)畫(huà)分為3種:AnimationDrawable(類(lèi))逐幀動(dòng)畫(huà);Tween補(bǔ)間動(dòng)畫(huà);property animation屬性動(dòng)畫(huà);
第1種的類(lèi)名:AnimationDrawable,在資料文件部份,這類(lèi)動(dòng)畫(huà)也屬于Drawable的1種,是Drawable的子類(lèi);
第2種的類(lèi)名:Animation,Animation是個(gè)抽象類(lèi),android提供了幾個(gè)具體的實(shí)現(xiàn)類(lèi)如TranslateAnimation,RotateAnimation,AlphaAnimation,ScaleAnimation;
第3種的類(lèi)名:Animator,Animator也是個(gè)抽象類(lèi),android提供了ValueAnimator和ObjectAnimator和Animatorset作為具體實(shí)現(xiàn)。其中ObjectAnimator繼承了ValueAnimator,前者1般情況下使用起來(lái)可以更方便,但有些特殊情況必須使用ValueAnimator. 而Animatorset可以對(duì)多個(gè)Animator對(duì)象包裹。
在這里主要就Animator進(jìn)行1些記錄:
定義屬性動(dòng)畫(huà)資源文件的格式舉例:
實(shí)例-實(shí)現(xiàn)不斷漸變的背風(fēng)景
res文件夾下建立animator文件夾,在該文件夾下建立
color_anim.xml
<?xml version="1.0" encoding="utf⑻"?>
<objectAnimator xmlns:Android="http://schemas.android.com/apk/res/android"
android:propertyName="backgroundColor"
android:duration="3000"
android:valueFrom="#FF8080"
android:valueTo="#8080FF"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:valueType="intType">
</objectAnimator>
其他文件
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/my_linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
</LinearLayout>
MainActivity.Java
package com.example.propertyanimation;
import android.os.Bundle;
import android.animation.AnimatorInflater;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import android.widget.LinearLayout;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout
Container=(LinearLayout) super.findViewById(R.id.my_linear);
container.addView(new MyAnimationView(this));
}
public class MyAnimationView extends View{
@SuppressLint("NewApi")
public MyAnimationView(Context context) {
super(context);
//加載動(dòng)畫(huà)資源
ObjectAnimator colorAnim=(ObjectAnimator) AnimatorInflater.loadAnimator(MainActivity.this, R.animator.color_anim);
/**
* 如果想要的動(dòng)畫(huà)類(lèi)型是Android系統(tǒng)所未知的,那末通過(guò)實(shí)現(xiàn)TypeEvaluator接口就可以夠創(chuàng)建自己的評(píng)價(jià)器。
* Android系統(tǒng)已知的類(lèi)型是int、float或色彩(color),分別有IntEvaluator、FloatEvaluator
* 和ArgbEvaluator類(lèi)型的評(píng)價(jià)器所支持。
*/
colorAnim.setEvaluator(new ArgbEvaluator());
//對(duì)該View本身利用屬性動(dòng)畫(huà)
colorAnim.setTarget(this);
//開(kāi)始指定動(dòng)畫(huà)
colorAnim.start();
}
}
}
屬性動(dòng)畫(huà)使用時(shí)有時(shí)會(huì)用到自定義的TypeEvaluator,自定義舉例:
如果想根據(jù)某個(gè)屬性TYPE來(lái)實(shí)現(xiàn)動(dòng)畫(huà),但是這個(gè)Type又不是Android系統(tǒng)內(nèi)置的,這個(gè)時(shí)候就需要?jiǎng)?chuàng)建1個(gè)自己的evaluator來(lái)實(shí)現(xiàn)了,并且新創(chuàng)建的type必須實(shí)現(xiàn)接口TypeEvaluator。Android系統(tǒng)內(nèi)置的type有int,float和color,他們對(duì)應(yīng)的evaluator是IntEvaluator、FloatEvaluator和ArgbEvaluator。接口TypeEvaluator內(nèi)只有1個(gè)方法,用來(lái)計(jì)算要實(shí)現(xiàn)動(dòng)畫(huà)屬性的值。
- /**
- * Interface for use with the {@link ValueAnimator#setEvaluator(TypeEvaluator)} function. Evaluators
- * allow developers to create animations on arbitrary property types, by allowing them to supply
- * custom evaluators for types that are not automatically understood and used by the animation
- * system.
- *
- * @see ValueAnimator#setEvaluator(TypeEvaluator)
- */
- public interface TypeEvaluator<T> {
- /**
- * This function returns the result of linearly interpolating the start and end values, with
- * <code>fraction</code> representing the proportion between the start and end values. The
- * calculation is a simple parametric calculation: <code>result = x0 + t * (x1 - x0)</code>,
- * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
- * and <code>t</code> is <code>fraction</code>.
- *
- * @param fraction The fraction from the starting to the ending values
- * @param startValue The start value.
- * @param endValue The end value.
- * @return A linear interpolation between the start and end values, given the
- * <code>fraction</code> parameter.
- */
- public T evaluate(float fraction, T startValue, T endValue);
- }
先看看Android系統(tǒng)內(nèi)置FloatEvaluator是怎樣弄的:
- public class FloatEvaluator implements TypeEvaluator<Number> {
- /**
- * This function returns the result of linearly interpolating the start and end values, with
- * <code>fraction</code> representing the proportion between the start and end values. The
- * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>,
- * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
- * and <code>t</code> is <code>fraction</code>.
- *
- * @param fraction The fraction from the starting to the ending values
- * @param startValue The start value; should be of type <code>float</code> or
- * <code>Float</code>
- * @param endValue The end value; should be of type <code>float</code> or <code>Float</code>
- * @return A linear interpolation between the start and end values, given the
- * <code>fraction</code> parameter.
- */
- public Float evaluate(float fraction, Number startValue, Number endValue) {
- float startFloat = startValue.floatValue();
- return startFloat + fraction * (endValue.floatValue() - startFloat);
- }
- }
還是舉個(gè)例子來(lái)測(cè)試1下,先看下面圖中的效果:

這個(gè)動(dòng)畫(huà)在Android-Property Animation(屬性動(dòng)畫(huà))中就實(shí)現(xiàn)過(guò)了,當(dāng)時(shí)是這么實(shí)現(xiàn)的:
- private void startValueAnimation(){
- if(mValueAnimator == null){
- mValueAnimator = ValueAnimator.ofFloat(0, 500);
- }
- mValueAnimator.setInterpolator(new AnticipateInterpolator());
- mValueAnimator.setTarget(mImageView);
- mValueAnimator.setDuration(3000);
- mValueAnimator.setRepeatCount(1);
- mValueAnimator.start();
- mValueAnimator.addUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- //同時(shí)設(shè)置X,Y 兩個(gè)屬性
- mImageView.setTranslationX((Float) animation.getAnimatedValue());
- mImageView.setTranslationY((Float) animation.getAnimatedValue());
- }
- });
- }
在動(dòng)畫(huà)update的時(shí)候同時(shí)更新View的X和Y屬性。另外,使用AnimatorSet也能夠?qū)崿F(xiàn)這類(lèi)動(dòng)畫(huà)效果。除這兩種以外還有無(wú)呢?就是自定義1個(gè)TypeEvaluator,主要代碼以下:
- private void startObjectAnimation() {
- ViewXYHolder viewXYHolder = new ViewXYHolder(mImageView);
- XYHolder startXY = new XYHolder(0f, 0f);
- XYHolder endXY = new XYHolder(500f, 500f);
- ObjectAnimator objectAnimator = ObjectAnimator.ofObject(viewXYHolder, "xY", new XYmEvaluator(), startXY, endXY);
- objectAnimator.setInterpolator(new LinearInterpolator());
- objectAnimator.setDuration(3000);
- objectAnimator.start();
- }
- public class XYmEvaluator implements TypeEvaluator {
- public Object evaluate(float fraction, Object startValue, Object endValue) {
- XYHolder startXY = (XYHolder) startValue;
- XYHolder endXY = (XYHolder) endValue;
- return new XYHolder(startXY.getX() + fraction * (endXY.getX() - startXY.getX()),
- startXY.getY() + fraction * (endXY.getY() - startXY.getY()));
- }
- }
- public class XYHolder{
- private float mX;
- private float mY;
- public XYHolder(float x, float y) {
- mX = x;
- mY = y;
- }
- public float getX() {
- return mX;
- }
- public void setX(float x) {
- mX = x;
- }
- public float getY() {
- return mY;
- }
- public void setY(float y) {
- mY = y;
- }
- }
- public class ViewXYHolder{
- private View imageView;
- public ViewXYHolder(View view){
- imageView = view;
- }
- //看到這個(gè)是否是感覺(jué)跟第1種方法1樣的感腳,只是封裝的不同
- public void setXY(XYHolder xyHolder) {
- imageView.setX(xyHolder.getX());
- imageView.setY(xyHolder.getY());
- }
- public XYHolder getXY() {
- return new XYHolder(imageView.getX(), imageView.getY());
- }
- }
而其實(shí),對(duì)這個(gè)例子,使用的對(duì)象是1個(gè)View,Android系統(tǒng)中有封裝View屬性動(dòng)畫(huà)的1個(gè)類(lèi):ViewPropertyAnimator,其簡(jiǎn)單使用方式以下:
- private void startViewPropertyAnimation(){
- ViewPropertyAnimator viewPropertyAnimator;
- viewPropertyAnimator = mImageView.animate().x(500).y(500);
- viewPropertyAnimator.setDuration(3000);
- viewPropertyAnimator.start();
- }
一樣也能實(shí)現(xiàn)上面的動(dòng)畫(huà)效果,只是只局限于View,不管方法怎樣變,但是終究原理都是1樣的,都是要同時(shí)改變X 和 Y兩個(gè)屬性的值。復(fù)雜1點(diǎn)的例子還是直接參考ApiDemo比較好,ApiDemo里面有個(gè)Custom Evaluator,值得學(xué)習(xí)! 最后引文作者提到了ViewPropertyAnimator類(lèi),這個(gè)類(lèi)源碼解釋的意思大概是:這個(gè)類(lèi)可以自動(dòng)并優(yōu)化view對(duì)象所觸及的某些屬性的動(dòng)畫(huà),與用單純的Animator控制view屬性動(dòng)畫(huà)不同的是: Animator更合適于只對(duì)view對(duì)象的1兩個(gè)屬性進(jìn)行操作,當(dāng)view的很多個(gè)屬性都需要?jiǎng)赢?huà)操作時(shí)用ViewPropertyAnimator比較好,緣由在于后者可以將多個(gè)屬性操作放在1次invalidate履行,即多個(gè)屬性的變化可以是調(diào)用1次刷新。 而單純Animator每個(gè)屬性的變化都要單獨(dú)調(diào)用1次invalidate進(jìn)行刷新。