动画

这里讲的动画框架是3.0之后的框架。

主要框架描述

Property Animation

通过动画的方式改变对象的属性

View Animation

对View支持简单的缩放、平移、旋转、透明度基本的动画

Drawable Animation

对图像进行序列展示

对于连续的图片展示可以使用drawable animation 对于对View简单的缩放、平移等动画可以使用view animation 对于需要复杂的动画用property animation 对于补间动画控件做动画并没有改变控件内部的属性值


Property Animation

1.基础类Animator

Animator是一个抽象类,是属性动画的基础类。不直接使用该类。

2.ValueAnimator

ValueAnimator简单的例子

 /**
 * ValueAnimator
 */
ValueAnimator animator = ValueAnimator.ofFloat(0, 360.0F);

/**
 * 更新动画
 */
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        mBtn1.setRotationX((Float) animation.getAnimatedValue());
    }
});

/**
 * 监听动画变化
 */
animator.addListener(new ValueAnimator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
        Logger.i("onAnimationStart");
    }

    @Override
    public void onAnimationEnd(Animator animation) {
        Logger.i("onAnimationEnd");
    }

    @Override
    public void onAnimationCancel(Animator animation) {
        Logger.i("onAnimationCancel");
    }

    @Override
    public void onAnimationRepeat(Animator animation) {
        Logger.i("onAnimationRepeat");
    }
});

/**
 * 设置重复次数
 */
animator.setRepeatCount(2);

animator.setDuration(500).start();
3.ObjectAnimator

简单的例子

 /**
 * ObjectAnimator
 */
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mBtn, "rotationX", 0.0F, 360.0F)
        .setDuration(500);
objectAnimator.setInterpolator(new AccelerateInterpolator());
objectAnimator.start();

在view可以设置的参数

//1、透明度:alpha  
public void setAlpha(float alpha)  

//2、旋转度数:rotation、rotationX、rotationY  
public void setRotation(float rotation)  
public void setRotationX(float rotationX)  
public void setRotationY(float rotationY)  

//3、平移:translationX、translationY  
public void setTranslationX(float translationX)   
public void setTranslationY(float translationY)  

//缩放:scaleX、scaleY  
public void setScaleX(float scaleX)  
public void setScaleY(float scaleY)
4.插值器
TimeInterpolator

参数input:input参数是一个float类型,它取值范围是0到1,表示当前动画的进度,取0时表示动画刚开始,取1时表示动画结束,取0.5时表示动画中间的位置,其它类推。 返回值:表示当前实际想要显示的进度。取值可以超过1也可以小于0,超过1表示已经超过目标值,小于0表示小于开始位置。

系统插值器列表
名字 意义
AccelerateDecelerateInterpolator 在动画开始与介绍的地方速率改变比较慢,在中间的时候加速
AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速
AnticipateInterpolator 开始的时候向后甩一点然后向前
AnticipateOvershootInterpolator 开始的时候向后甩一点然后向前超过设定值一点然后返回
BounceInterpolator 动画结束的时候弹起,类似皮球落地
CycleInterpolator 动画循环播放特定的次数回到原点,速率改变沿着正弦曲线
DecelerateInterpolator 在动画开始的地方快然后慢
LinearInterpolator 以常量速率改变
OvershootInterpolator 向前超过设定值一点然后返回
自定义插值器
/***
 *
 * 预览android动画
 *
 * http://inloop.github.io/interpolator/
 */
public class MyInterpolator implements TimeInterpolator {

    @Override
    public float getInterpolation(float input) {
        /**
         * input float类型 0.0-1.0
         */
        return cubicHermite(input, 0.0f, 1.0f, 4.0f, 4.0f);
    }

    private float cubicHermite(float t, float p0, float p1, float m0, float m1){
        float t2 = t*t;
        float t3 = t2*t;
        return (2*t3 - 3*t2 + 1)*p0 + (t3-2*t2+t)*m0 + (-2*t3+3*t2)*p1 + (t3-t2)*m1;
    }

}
5.转换器(TypeEvaluator)
默认的转换器
  • IntEvaluator,对int类型数据进行转换
  • FloatEvalutar,对float类型数据进行转换
颜色转换器
  • ArgbEvalutor,对颜值值(argb)类型数据进行转换
自定义转换器
/**
 *
 * 转换器
 *
 */
public class MyTypeEvaluator implements TypeEvaluator<Float> {

    /**
     *
     * 根据插值转换值
     *
     * @param fraction 插值器的因子
     * @param startValue 起始的值
     * @param endValue 最终的值
     * @return
     */
    @Override
    public Float evaluate(float fraction, Float startValue, Float endValue) {
        float startInt = startValue;
        float result = (int) (startInt + fraction * (endValue - startInt));
        Logger.i("result:" + result + "==startInt:" + startInt + "==fraction:" + fraction + "==endValue:" + endValue);
        return result;
    }
}
6.ofObject

可以传进去任何类型的变量。

public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values);

例子 StringEvaluator.java

/**
 *
 * 起始值和结束值长度需要一样
 *
 */
public class StringEvaluator implements TypeEvaluator<String>{

    @Override
    public String evaluate(float fraction, String startValue, String endValue) {
        if(startValue.length()!=endValue.length()){
            return "startValue!=endValue";
        }
        int size = startValue.length();
        int pos = (int)(fraction*size);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(startValue.substring(0,pos));
        stringBuilder.append(endValue.substring(pos,endValue.length()));
        Logger.i("size:"+size +"==pos:"+pos+"==string"+stringBuilder.toString());
        return stringBuilder.toString();
    }
}
/**
 * 将A全部替换为B
 */
String startString = "AAAAAAAAAAAAAAAAAAAAAAAAAA";
String endString =   "BBBBBBBBBBBBBBBBBBBBBBBBBB";
ValueAnimator animator = ValueAnimator.ofObject(new StringEvaluator(), startString, endString);
animator.setDuration(2500);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        mStringTV.setText((String) animation.getAnimatedValue());
    }
});
animator.start();
7.在自定义View中使用动画
使用ValueAnimator制作动画

EllipseAnimationView.java

package gift.witch.android.ae.animation;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.BounceInterpolator;


/**
 *
 * 自定义椭圆压扁动画
 *
 */
public class EllipseAnimationView extends View {

    private Paint mPaint;
    private RectF mRectF;
    private RectF mStart;
    private RectF mEnd;

    public EllipseAnimationView(Context context) {
        super(context);
        init();
    }

    public EllipseAnimationView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public EllipseAnimationView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    /**
     * 初始化
     */
    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.FILL);
        mStart= new RectF();
        mStart.set(0, 0, 200, 200);
        mEnd = new RectF();
        mEnd.set(mStart.left, mStart.top + 50, mStart.right, mStart.bottom - 50);
        mRectF = mStart;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawOval(mRectF, mPaint);
    }

    /**
     *
     * 启动动画
     *
     */
    public void doAnim() {

        ValueAnimator animator = ValueAnimator.ofObject(new RectFEvaluator(), mStart, mEnd);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mRectF = (RectF) animation.getAnimatedValue();
                invalidate();
            }
        });
        animator.setDuration(1000);
        animator.setInterpolator(new BounceInterpolator());
        animator.start();
    }

}
8.使用自定义ObjectAnimator制作动画
package gift.witch.android.ae.animation;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

/**
 *
 * 通过ObjectAnimator对View进行动画
 *
 */
public class RectFAnimationView extends View {

    private Paint mPaint;
    private RectF mRectF;
    private RectF mStart;
    private RectF mEnd;

    public RectFAnimationView(Context context) {
        super(context);
        init();
    }

    public RectFAnimationView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public RectFAnimationView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    /**
     * 初始化
     */
    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.FILL);
        mStart= new RectF();
        mStart.set(0, 0, 200, 200);
        mRectF = mStart;

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(mRectF, mPaint);
    }

    /**
     * 设置动画
     * @param rectF
     */
    public void setRectF(RectF rectF){
        mRectF = rectF;
        invalidate();
    }

    /**
     * 在没有初始化值的时候会调用get方法
     * @return
     */
    public RectF getRectF(){
        return mStart;
    }

}

使用

RectF end = new RectF();
end.set(0, 50, 0, 150);
ObjectAnimator objectAnimator = ObjectAnimator.ofObject(mRectFAnimationView, "rectF",new RectFEvaluator(), end)
        .setDuration(500);
objectAnimator.setInterpolator(new BounceInterpolator());
objectAnimator.start();
9.Keyframe关键帧

简单的例子

Keyframe frame0 = Keyframe.ofFloat(0f, 0);
Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);
Keyframe frame2 = Keyframe.ofFloat(0.2f, 20f);
Keyframe frame3 = Keyframe.ofFloat(0.3f, -20f);
Keyframe frame4 = Keyframe.ofFloat(0.4f, 20f);
Keyframe frame5 = Keyframe.ofFloat(0.5f, -20f);
Keyframe frame6 = Keyframe.ofFloat(0.6f, 20f);
Keyframe frame7 = Keyframe.ofFloat(0.7f, -20f);
Keyframe frame8 = Keyframe.ofFloat(0.8f, 20f);
Keyframe frame9 = Keyframe.ofFloat(0.9f, -20f);
Keyframe frame10 = Keyframe.ofFloat(1, 0);
PropertyValuesHolder frameHolder = PropertyValuesHolder.ofKeyframe("rotation",frame0,frame1,frame2,frame3,frame4,frame5,frame6,frame7,frame8,frame9,frame10);

Animator animator = ObjectAnimator.ofPropertyValuesHolder(mKeyFrame,frameHolder);
animator.setDuration(1000);
animator.start();

Keyframe的子类 1.ObjectKeyframe 2.IntKeyframe 3.FloatKeyframe 区别在于值的不同

10.AnimatorSet

例子

ObjectAnimator tv1BgAnimator = ObjectAnimator.ofInt(mBtn10, "BackgroundColor",  0xffff00ff, 0xffffff00, 0xffff00ff);
/**
 * 延时
 */
tv1BgAnimator.setStartDelay(1000);
ObjectAnimator tv1TranslateY = ObjectAnimator.ofFloat(mBtn10, "translationY", 0, 300, 0);
ObjectAnimator tv2TranslateY = ObjectAnimator.ofFloat(mBtn10, "rotation", 0, 270, 90, 180, 0);

AnimatorSet animatorSet = new AnimatorSet();


/**
 * 按序列执行动画
 */
//playSequentially(Animator... items);
//playSequentially(List<Animator> items);
animatorSet.playSequentially(tv1BgAnimator,tv1TranslateY,tv2TranslateY);


/**
 *同时执行
 */
//playTogether(Animator... items);
//playTogether(Collection<Animator> items);
//animatorSet.playTogether(tv1BgAnimator,tv1TranslateY,tv2TranslateY);



/**
 *t 通过AnimatorSet.Builder设置动画顺序
 */
AnimatorSet.Builder builder = animatorSet.play(tv1BgAnimator);
builder.with(tv1TranslateY);

/**
 //和前面动画一起执行
 public Builder with(Animator anim)
 //执行前面的动画后才执行该动画
 public Builder before(Animator anim)
 //执行先执行这个动画再执行前面动画
 public Builder after(Animator anim)
 //延迟n毫秒之后执行动画
 public Builder after(long delay)
 */
animatorSet.setDuration(1000);
animatorSet.start();
可参考地址

自定义控件三部曲之动画篇(四)——ValueAnimator基本使用 http://blog.csdn.net/harvic880925/article/details/50525521

View Animation

视图动画分为两种,Tween Animation(补间动画)和Frame Animation(帧动画)。

补间动画

xml资源文件设置
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@[package:]anim/interpolator_resource"
    android:shareInterpolator=["true" | "false"] >
    <alpha
        android:fromAlpha="float"
        android:toAlpha="float" />
    <scale
        android:fromXScale="float"
        android:toXScale="float"
        android:fromYScale="float"
        android:toYScale="float"
        android:pivotX="float"
        android:pivotY="float" />
    <translate
        android:fromXDelta="float"
        android:toXDelta="float"
        android:fromYDelta="float"
        android:toYDelta="float" />
    <rotate
        android:fromDegrees="float"
        android:toDegrees="float"
        android:pivotX="float"
        android:pivotY="float" />
    <set>
        ...
    </set>
</set>
调用资源xml
AnimationUtils.loadAnimation(Context context, @AnimRes int id)
代码创建
/**
 * Animation
 */
Animation animation = new ScaleAnimation(1,0.5f,1,0.5f);
/**
 * 设置时间
 */
animation.setDuration(3000);
/**
 * 停留在最后的状态
 */
animation.setFillAfter(true);
//animation.start();

Animation animation2 = new TranslateAnimation(0,100,0,100);
animation2.setDuration(3000);
/**
 * 重复次数 默认是0
 */
animation2.setRepeatCount(1);
/**
 * 停留在初始状态
 */
animation2.setFillBefore(true);

AnimationSet animationSet = new AnimationSet(true);
animationSet.setFillAfter(true);
animationSet.addAnimation(animation);
animationSet.addAnimation(animation2);

/**
 * 启动动画组合
 */
mBtn5.startAnimation(animationSet);

Drawable Animation

xml资源设置
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot=["true" | "false"] >
    <item
        android:drawable="@[package:]drawable/drawable_resource_name"
        android:duration="integer" />
</animation-list>
调用xml
mBgTV = (TextView)findViewById(R.id.bg);
        mBgTV.setBackgroundResource(R.drawable.frame_anim);
        mBgTV.setOnClickListener(this);
...
AnimationDrawable animation = (AnimationDrawable) mBgTV.getBackground();
/**
 * 增加帧
*/
//animation.addFrame();
/**
* 启动动画
*/
animation.start();
/**
* 停止动画
*/
animation.stop();
可参考地址

自定义控件三部曲之动画篇(一)——alpha、scale、translate、rotate、set的xml属性及用法 http://blog.csdn.net/harvic880925/article/details/39996643

results matching ""

    No results matching ""