Tween 动画、Frame 动画
一张一张的图片按照顺序和时间进行一帧一帧的播放
思路:将图片资源作为背景图片,依次播放。用到的类:AnimationDrawable
1 将资源图片导入到对应的 drawable-xxx 或drawable 目录中
2 在其目录下,创建xml文件,根节点选择 animation-list
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false" > //自动执行,true,停在最后一帧(只播放一次),false,循环播放
<item
android:drawable="@drawable/logo1"
android:duration="850"> //设置持续时长
item>
<item
android:drawable="@drawable/logo2"
android:duration="850">
item>
animation-list>
3 java代码
ImageView iv = (ImageView) findViewById(R.id.iv); //找到图片控件
iv.setBackgroundResource(R.drawable.logo); //导入资源文件
AnimationDrawable anim = (AnimationDrawable) iv.getBackground();
anim.start(); //开始播放动画
方法一:添加多个帧 Drawable
mAnimationDrawable = new AnimationDrawable();
mAnimationDrawable.setOneShot(false);//是否执行一次
for(int i=0;i<11;i++){ //添加多个帧 Drawable
Drawable frame = getResources().getDrawable(R.drawable.girl_1+i);
mAnimationDrawable.addFrame(frame, 200);
}
mImageView.setImageDrawable(mAnimationDrawable); //设置帧动画,默认是停止状态
方法二:引用xml 帧动画drawable
// 引用xml 帧动画drawable
mAnimationDrawable=(AnimationDrawable)getResources().getDrawable(R.drawable.frame);
mImageView.setImageDrawable(mAnimationDrawable);
补间动画也叫渐变动画,对特定的对象做图像变换如平移、缩放、旋转、淡出/淡入等
动画类型 | XML节点 | 使用的java类 |
---|---|---|
透明 | alpha | AlphaAnimation |
缩放 | scale | ScaleAnimation |
移动 | translate | TranslateAnimation |
旋转 | rotate | RoateAnimation |
动画集合 | set | AnimationSet |
缩放
fromXScale 起始X方向相对自身的缩放比例,浮点值。1.0:无变化,0.5缩小一倍
toXScale 结尾X方向相对自身的缩放比例
fromYScale 起始Y方向相对自身的缩放比例
toYScale 结尾Y方向相对自身的缩放比例
pivotX 缩放起点的X轴坐标,可以是数值,百分数,百分数p
数值:如50,当前View的左上角X轴坐标 + 50px作为动画起点
百分数:如50%,当前View的左上角X轴坐标 + 自身X轴方向宽度的50%作为动画起点
百分数p:如50%P,当前View左上角X轴坐标 + 父控件X轴方向宽度50%作为动画起点
pivotY 缩放起点的X轴坐标,同pivotX
透明
fromAlpha 动画开始时的透明度,从0.0-1.0,0.0:全透明,1.0:完全不透明
toAlpha 动画结束时的透明度
旋转
fromDegrees 开始旋转的角度位置,正直:顺时针方向度数,反之同理
toDegrees 结束时旋转到的角度位置
pivotX 同缩放
pivotY 同缩放
平移
fromXDelta 起始点的X轴坐标,具体数值同pivotX
fromYDelta 起始点的Y轴坐标
toXDelta 结束点的X轴坐标
toYDelta 结束点的Y轴坐标
通用属性
duration 动画持续时间
fillAfter 设为true,动画结束时,保持动画最后时状态
fillBefore 设置true,动画结束时,动画还原到初始化状态
fillEnabled 同fillBefore
repeatCount 重复次数
repeatMode 重复类型,reverse:倒序播放,restart:重新播放
duration 单次动画持续时间,单位毫秒
在res/anim 目录下创建set.xml文件
<--!各标签中属性参照动画类的构造方法中的参数及常用方法 -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="false" >
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="2000"
android:repeatCount="infinite"
android:repeatMode="reverse" >
alpha>
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="2"
android:repeatMode="reverse"
android:toDegrees="360" >
rotate>
set>
Animation set = AnimationUtils.loadAnimation(this, R.anim.set); //单个动画所用方法一致
iv.startAnimation(set);
常用类构造方法解析
AlphaAnimation(float fromAlpha, float toAlpha);
//fromAlpha: 动画的起始alpha值 (范围:0:完全透明 -1:完全不透明)
//toAlpha:终止的值,动画结束的值
TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
int fromYType,float fromYValue,int toYType, float toYValue)
//fromXType(起点,相对于原点偏移方式)
Animation.ABSOLUTE 绝对值,像素值
Animation.RELATIVE_TO_SELF 相对于自己
Animation.RELATIVE_TO_PARENT 相对于父控件
//fromXValue(起点,相对于原点偏移量),绝对值/百分比
ScaleAnimation(float fromX,float toX,float fromY,float toY,
int pivotXType,float pivotXValue,int pivotYType, float pivotYValue)
//fromX: 缩放起始比例-水平方向
//toX: 缩放最终比例-水平方向
//pivotXType(中心点相较于原点 x方向的类型):
Animation.ABSOLUTE
Animation.RELATIVE_TO_SELF
Animation.RELATIVE_TO_PARENT
//pivotXValue: 绝对值/百分比
RotateAnimation(float fromDegrees,float toDegrees,int pivotXType,float pivotXValue, int pivotYType, float pivotYValue)
动画类的通用方法
setDuration(3000); // 每次动画持续时间3秒
setFillAfter(true); // 动画最后停留在终止的状态
setRepeatCount(3); // 动画重复的次数
setRepeatMode(Animation.REVERSE); // REVERSE: 反转模式 RESTART:重新开始
setInterpolator(new BounceInterpolator(2f)); // 设置特效
start();
cancle();
AnimationSet set = new AnimationSet(false);
AlphaAnimation al = new AlphaAnimation(0,1);//范围:0:完全透明,1:完全不透明
RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0,
Animation.RELATIVE_TO_SELF,1f,
Animation.RELATIVE_TO_SELF,0,
Animation.RELATIVE_TO_SELF,1f);
set.addAnimation(al);
set.addAnimation(ra);
set.addAnimation(sa);
set.addAnimation(ta);
iv.startAnimation(set);
引入原因:补间动画功能只能覆盖移动,缩放,旋转,透明四种对view的操作,局限性大。只改变view的显示效果,不改变view的属性
java类 | XML标签 |
---|---|
ValueAnimator | animator |
ObjectAnimator | objectAnimator |
AnimatorSet | set set标签可嵌套 |
//创建res/animator/objectAnimator资源
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="alpha"
android:duration="3000"
android:repeatCount="3"
android:repeatMode="reverse"
android:valueFrom="0.0"
android:valueTo="1.0">
</objectAnimator>
//AnimatorInflater应用
Animator animator = AnimatorInflater.loadAnimator(this,R.animator.alpha); //加载动画资源
animator.setTarget(iv); //指定要显示动画的控件
animator.start(); //开启动画
//translationX:围绕X轴旋转,translationX:围绕Y轴旋转,setRotation:围绕Z轴旋转,其他同理
//右,下,上为正
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "alpha",new float[]{0.0f,0.2f,0.4f,0.6f,0.8f,1.0f});
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX",new float[] {10f,20f,40f,70f,100f});
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "scaleX",new float[] {1f,2f,3f,4f,5f,6f});
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "rotationY",new float[] {90f,180f,270f,360f});
//动画集合
AnimatorSet set = new AnimatorSet();
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX",new float[] {10f,20f,30f,40f,60f});
ObjectAnimator ob = ObjectAnimator.ofFloat(iv, "translationY",new float[] {-10f,-20f,-30f,-40f});
set.playTogether(oa, ob);
set.setDuration(3000);
set.start();
组合动画功能实现。
play():传入一个Animator对象(ValueAnimator或ObjectAnimator ),返回一个AnimatorSet.Builder实例
AnimatorSet.Builder方法:
after(Animator anim) | 现有动画在传入动画后执行 |
---|---|
after(long delay) | 现有动画延迟指定毫秒后执行 |
before(Animator anim) | 现有动画在传入动画前执行 |
with(Animator anim) | 现有动画与传入动画同时执行 |
ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f); ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
AnimatorSet animSet = new AnimatorSet();
animSet.play(rotate).with(fadeInOut).after(moveIn);
animSet.setDuration(5000);
animSet.start();
属性动画的运行机制是通过不断地对值进行操作来实现的,ValueAnimator实现初始值与结束值间值运算
ofFloat() 、 ofInt() 、 ofObject() | 动画范围 |
---|---|
setStartDelay() | 动画延迟播放的时间 |
setRepeatCount() | 动画循环播放的次数 |
setRepeatMode() | 循环播放的模式,RESTART:重播,REVERSE:倒叙播放 |
//ValueAnimator ofObject(TypeEvaluator evaluator, Object... values);
ValueAnimator animator = ValueAnimator.ofObject(new CharEvaluator(),new Character('A'),new Character('Z')); //CharEvaluator内数值变化与其他类似,对应ASCII码表
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
char text = (char)animation.getAnimatedValue();
tv.setText(String.valueOf(text));
}
});
animator.setDuration(10000);
animator.setInterpolator(new AccelerateInterpolator());
animator.start();
使用ofObject(),自定义CharEvaluator实现园缩放特效:链接
对任意对象的任意属性进行动画操作
ObjectAnimator ofFloat(Object target, String propertyName, float... values);
//参数:控件,控件属性,变化范围
在ValueAnimator中,我们要通过添加监听器来监听当前数字值
在ObjectAnimator中,则是先根据属性值拼装成对应的set函数的名字
set函数拼写:属性首字母大小 + set/Set + 对应set函数名
提供更易懂API,实现属性动画。支持连缀用法
1 ViewPropertyAnimator功能均建立在View类新增的animate()方法之上,创建并返回一个ViewPropertyAnimator实例
2 ViewPropertyAnimator隐式启动动画,不需要调用start()。此机制对于组合动画同样有效
ObjectAnimator extends ValueAnimator
ValueAnimator extends Animator
ViewPropertyAnimator animator = textview.animate(); //生成ViewPropertyAnimator对象
animator.alpha(0f); //将当前的textview变成透明状态
animator.x(500).y(500); //让textview运动到500,500这个坐标点
animator.x(500).y(500).setDuration(5000); //设定动画的运行时长
animator.x(500).y(500).setDuration(5000)
.setInterpolator(new BounceInterpolator()); //使用Interpolator
addListener ():任何继承自Animator 的类共有方法
Anim.addListener(new AnimatorListener() {
@Override //动画开始的时候调用
public void onAnimationStart(Animator animation) {}
@Override //动画重复执行的时候调用
public void onAnimationRepeat(Animator animation) {}
@Override //动画结束的时候调用
public void onAnimationEnd(Animator animation) {}
@Override //动画被取消的时候调用
public void onAnimationCancel(Animator animation) {}
});
AnimatorListenerAdapter:系统提供的适配器类,解决接口繁琐问题
Anim.addListener(new AnimatorListenerAdapter() { //可自定义实现其中方法
@Override
public void onAnimationEnd(Animator animation) {}
});
转换器,将进度转换为对应的数值位置
从定义动画的数字区间到通过AnimatorUpdateListener中得到当前动画所对应数值的整个过程
ofInt(0,400):指定动画的数字区间,从0到400
插值器Interpolator:动画开始后,通过Interpolator返回当前动画的数字进度(百分制,小数表示,如0.2)
Evaluator:将从插值器Interpolator返回的数字进度转成对应的数字值:当前的值 = 100 + (400 - 100)* 显示进度
监听器:通过在AnimatorUpdateListener监听器使用animation.getAnimatedValue()函数拿到Evaluator返回值
//ofInt()对应的Evaluator类名叫IntEvaluator,其ofFloat()同理
ValueAnimator animator = ValueAnimator.ofInt(0,600); //调用的是ofInt()
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int curValue = (int)animation.getAnimatedValue(); //可强转为int
}
});
animator.setDuration(1000);
animator.setEvaluator(new IntEvaluator()); //设置系统IntEvaluator
animator.setInterpolator(new BounceInterpolator());
animator.start();
系统实现TypeEvaluator接口的有:IntEvaluator,FloatEvaluator,PointEvaluator,IntArrayEvaluator,FloatArrayEvaluator,RectEvaluator,ArgbEvaluator,PointFEvaluator
//自定义MyEvaluator实现TypeEvaluator,注意泛型
public class MyEvaluator implements TypeEvaluator<Integer> {
@Override
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
int startInt = startValue;
return (int)(200+startInt + fraction * (endValue - startInt));
}
}
//实现动画
ValueAnimator animator = ValueAnimator.ofInt(0,400);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int curValue = (int)animation.getAnimatedValue();
}
});
animator.setDuration(1000);
animator.setEvaluator(new MyEvaluator());
animator.start();
颜色值过渡转换
高级进阶:https://github.com/harvic/BlogResForGitHub
ValueAnimator animator = ValueAnimator.ofInt(0xffffff00,0xff0000ff); //颜色范围
animator.setEvaluator(new ArgbEvaluator());
animator.setDuration(3000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int curValue = (int)animation.getAnimatedValue(); //返回值可作为空间的背景颜色
tv.setBackgroundColor(curValue);
}
});
animator.start();
插值器,控制动画变化速率与类型。在属性动画中,颜色变化随速率变化。系统默认的Interpolator为AccelerateDecelerateInterpolator
实现类 | 意义 |
---|---|
AccelerateDecelerateInterpolator | 中间快,首尾慢 |
AccelerateInterpolator | 越来越快 |
AnticipateInterpolator | 开始的时候向后然后向前甩 |
AnticipateOvershootInterpolator | 开始的时候向后然后向前甩一定值后返回最后的值 |
BounceInterpolator | 结束时弹起 |
CycleInterpolator | 循环播放,速率沿正弦曲线改变 |
DecelerateInterpolator | 开始快,越来越慢 |
LinearInterpolator | 匀速 |
OvershootInterpolator | 向前甩一定值后再回到原来位置 |
//自定义DecelerateAccelerateInterpolator实现TimeInterpolator接口
//input:随着动画运行而变化,范围:0~1。动画开始时为0,结束时为1,中间在0~1间变化
public class DecelerateAccelerateInterpolator implements TimeInterpolator{
@Override
public float getInterpolation(float input) { //先减速后加速
float result;
if (input <= 0.5) {
result = (float) (Math.sin(Math.PI * input)) / 2;
} else {
result = (float) (2 - Math.sin(Math.PI * input)) / 2;
}
return result;
}
}