程序员人生 网站导航

属性动画资料文件如何编写?property-animation资源文件 属性动画如何自定义TypeEvaluator

栏目:综合技术时间:2017-02-06 08:33:02

android动画分为3种:AnimationDrawable(类)逐帧动画;Tween补间动画;property animation属性动画;

第1种的类名:AnimationDrawable,在资料文件部份,这类动画也属于Drawable的1种,是Drawable的子类;

第2种的类名:Animation,Animation是个抽象类,android提供了几个具体的实现类如TranslateAnimation,RotateAnimation,AlphaAnimation,ScaleAnimation;

第3种的类名:Animator,Animator也是个抽象类,android提供了ValueAnimator和ObjectAnimator和Animatorset作为具体实现。其中ObjectAnimator继承了ValueAnimator,前者1般情况下使用起来可以更方便,但有些特殊情况必须使用ValueAnimator.   而Animatorset可以对多个Animator对象包裹。


在这里主要就Animator进行1些记录:

定义属性动画资源文件的格式举例:


实例-实现不断渐变的背风景


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);
//加载动画资源
ObjectAnimator colorAnim=(ObjectAnimator) AnimatorInflater.loadAnimator(MainActivity.this, R.animator.color_anim);
/**
* 如果想要的动画类型是Android系统所未知的,那末通过实现TypeEvaluator接口就可以够创建自己的评价器。
* Android系统已知的类型是int、float或色彩(color),分别有IntEvaluator、FloatEvaluator
* 和ArgbEvaluator类型的评价器所支持。
*/
colorAnim.setEvaluator(new ArgbEvaluator());
//对该View本身利用属性动画
colorAnim.setTarget(this);
//开始指定动画
colorAnim.start();
}
}
}



属性动画使用时有时会用到自定义的TypeEvaluator,自定义举例:

如果想根据某个属性TYPE来实现动画,但是这个Type又不是Android系统内置的,这个时候就需要创建1个自己的evaluator来实现了,并且新创建的type必须实现接口TypeEvaluator。Android系统内置的type有int,float和color,他们对应的evaluator是IntEvaluator、FloatEvaluator和ArgbEvaluator。接口TypeEvaluator内只有1个方法,用来计算要实现动画属性的值。    

[java] view plain copy
  1. /** 
  2.  * Interface for use with the {@link ValueAnimator#setEvaluator(TypeEvaluator)} function. Evaluators 
  3.  * allow developers to create animations on arbitrary property types, by allowing them to supply 
  4.  * custom evaluators for types that are not automatically understood and used by the animation 
  5.  * system. 
  6.  * 
  7.  * @see ValueAnimator#setEvaluator(TypeEvaluator) 
  8.  */  
  9. public interface TypeEvaluator<T> {  
  10. /** 
  11.      * This function returns the result of linearly interpolating the start and end values, with 
  12.      * <code>fraction</code> representing the proportion between the start and end values. The 
  13.      * calculation is a simple parametric calculation: <code>result = x0 + t * (x1 - x0)</code>, 
  14.      * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>, 
  15.      * and <code>t</code> is <code>fraction</code>. 
  16.      * 
  17.      * @param fraction   The fraction from the starting to the ending values 
  18.      * @param startValue The start value. 
  19.      * @param endValue   The end value. 
  20.      * @return A linear interpolation between the start and end values, given the 
  21.      *         <code>fraction</code> parameter. 
  22.      */  
  23. public T evaluate(float fraction, T startValue, T endValue);  
  24.   
  25. }  
先看看Android系统内置FloatEvaluator是怎样弄的:
[java] view plain copy
  1. public class FloatEvaluator implements TypeEvaluator<Number> {  
  2. /** 
  3.      * This function returns the result of linearly interpolating the start and end values, with 
  4.      * <code>fraction</code> representing the proportion between the start and end values. The 
  5.      * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>, 
  6.      * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>, 
  7.      * and <code>t</code> is <code>fraction</code>. 
  8.      * 
  9.      * @param fraction   The fraction from the starting to the ending values 
  10.      * @param startValue The start value; should be of type <code>float</code> or 
  11.      *                   <code>Float</code>  
  12. * @param endValue   The end value; should be of type <code>float</code> or <code>Float</code> 
  13. * @return A linear interpolation between the start and end values, given the 
  14.      *         <code>fraction</code> parameter. 
  15.      */  
  16. public Float evaluate(float fraction, Number startValue, Number endValue) {  
  17. float startFloat = startValue.floatValue();  
  18.         return startFloat + fraction * (endValue.floatValue() - startFloat);  
  19. }  
  20. }  
还是举个例子来测试1下,先看下面图中的效果:

这个动画在Android-Property Animation(属性动画)中就实现过了,当时是这么实现的:
[java] view plain copy
  1. private void startValueAnimation(){  
  2.     if(mValueAnimator == null){  
  3.         mValueAnimator = ValueAnimator.ofFloat(0500);  
  4.     }  
  5.     mValueAnimator.setInterpolator(new AnticipateInterpolator());  
  6.     mValueAnimator.setTarget(mImageView);  
  7.     mValueAnimator.setDuration(3000);  
  8.     mValueAnimator.setRepeatCount(1);  
  9.     mValueAnimator.start();  
  10.     mValueAnimator.addUpdateListener(new AnimatorUpdateListener() {  
  11.         @Override  
  12.         public void onAnimationUpdate(ValueAnimator animation) {  
  13.         //同时设置X,Y 两个属性  
  14.             mImageView.setTranslationX((Float) animation.getAnimatedValue());  
  15.             mImageView.setTranslationY((Float) animation.getAnimatedValue());  
  16.         }  
  17.     });  
  18. }  
在动画update的时候同时更新View的X和Y属性。另外,使用AnimatorSet也能够实现这类动画效果。
除这两种以外还有无呢?就是自定义1个TypeEvaluator,主要代码以下:
[java] view plain copy
  1. private void startObjectAnimation() {  
  2.     ViewXYHolder viewXYHolder = new ViewXYHolder(mImageView);  
  3.     XYHolder startXY = new XYHolder(0f, 0f);  
  4.     XYHolder endXY = new XYHolder(500f, 500f);  
  5.     ObjectAnimator objectAnimator = ObjectAnimator.ofObject(viewXYHolder, "xY"new XYmEvaluator(), startXY, endXY);  
  6.     objectAnimator.setInterpolator(new LinearInterpolator());  
  7.     objectAnimator.setDuration(3000);  
  8.     objectAnimator.start();  
  9. }  
  10.   
  11. public class XYmEvaluator implements TypeEvaluator {  
  12.     public Object evaluate(float fraction, Object startValue, Object endValue) {  
  13.             XYHolder startXY = (XYHolder) startValue;  
  14.             XYHolder endXY = (XYHolder) endValue;  
  15.         return new XYHolder(startXY.getX() + fraction * (endXY.getX() - startXY.getX()),  
  16.             startXY.getY() + fraction * (endXY.getY() - startXY.getY()));  
  17.     }  
  18. }  
  19.   
  20. public class XYHolder{  
  21.     private float mX;  
  22.     private float mY;  
  23.   
  24.     public XYHolder(float x, float y) {  
  25.     mX = x;  
  26.     mY = y;  
  27. }  
  28.   
  29. public float getX() {  
  30.     return mX;  
  31. }  
  32.   
  33. public void setX(float x) {  
  34.     mX = x;  
  35. }  
  36.   
  37. public float getY() {  
  38.     return mY;  
  39. }  
  40.   
  41. public void setY(float y) {  
  42.     mY = y;  
  43.     }  
  44. }  
  45.   
  46. public class ViewXYHolder{  
  47.     private View imageView;  
  48.     public ViewXYHolder(View view){  
  49.         imageView = view;  
  50.     }  
  51.   
  52. //看到这个是否是感觉跟第1种方法1样的感脚,只是封装的不同  
  53. public void setXY(XYHolder xyHolder) {  
  54.     imageView.setX(xyHolder.getX());  
  55.     imageView.setY(xyHolder.getY());  
  56. }  
  57.   
  58. public XYHolder getXY() {  
  59.     return new XYHolder(imageView.getX(), imageView.getY());  
  60. }  
  61. }  
而其实,对这个例子,使用的对象是1个View,Android系统中有封装View属性动画的1个类:ViewPropertyAnimator,其简单使用方式以下:
[html] view plain copy
  1. private void startViewPropertyAnimation(){  
  2.     ViewPropertyAnimator viewPropertyAnimator;  
  3.     viewPropertyAnimator = mImageView.animate().x(500).y(500);  
  4.     viewPropertyAnimator.setDuration(3000);  
  5.     viewPropertyAnimator.start();  
  6. }  
一样也能实现上面的动画效果,只是只局限于View,不管方法怎样变,但是终究原理都是1样的,都是要同时改变X 和 Y两个属性的值。
复杂1点的例子还是直接参考ApiDemo比较好,ApiDemo里面有个Custom Evaluator,值得学习! 最后引文作者提到了ViewPropertyAnimator类,这个类源码解释的意思大概是:这个类可以自动并优化view对象所触及的某些属性的动画,与用单纯的Animator控制view属性动画不同的是: Animator更合适于只对view对象的1两个属性进行操作,当view的很多个属性都需要动画操作时用ViewPropertyAnimator比较好,缘由在于后者可以将多个属性操作放在1次invalidate履行,即多个属性的变化可以是调用1次刷新。 而单纯Animator每个属性的变化都要单独调用1次invalidate进行刷新。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐