动画
这里讲的动画框架是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