补间动画
原理:
通过确定开始和结束时的视图样式, 中间动画的变化过程由系统来补全。
作用对象:
作用于View对象,不可作用于View的颜色,背景等属性
分类:
- 平移(Translate)
- 缩放(Scale)
- 旋转(Rotate)
- 透明度(Alpha)
对应的具体实现类
名称 | 原理 | 实现类 |
---|---|---|
平移动画(Translate) | 移动视图的位置 | TranslateAnimation |
缩放动画(Scale) | 放大或者缩小视图大小 | ScaleAnimation |
旋转动画(Rotate) | 旋转视图 | RotateAnimation |
透明动画(Alpha) | 改变视图的透明度 | AlphaAnimation |
TIPS:
补间动画只会改变View的视觉效果图,在ScalAnimation和TranslateAnimation中,不会改变View在屏幕上的位置,所以就会导致在执行TranslateAniamtion时,点击平移的View不会触发click监听,只有点击它原来的位置时才会触发click监听。
***4种动画(包括set组合动画)共有的属性:***
Animation属性 | 解释 |
---|---|
android:duration | 动画执行的时间 |
android:fillAfter | 如果为true,那么动画执行完就会定格在执行完的那个画面,也就是动画的最后一帧,不会恢复到原位。优先于fillBefore值,默认为false |
android:fillBefore | 动画播放完后,视图是否会停留在动画开始的状态。只有当android:fillEnable为true时,才有效 |
android:fillEnabled | 是否考虑android:fillBefore的值。只要为true时,android:fillBefore的值才会被考虑。 |
android:interpolator | 设置插值器,控制动画不同时间段的速度,默认是加速减速插值器。 |
android:repeatCount | 动画重复的次数,所以总共会运行的动画次数是这个重复次数+1;为infinite时无限重复 |
android:repeatMode | 动画重复的方式,有两个值,reverse 和 restart。reverse表示动画会正反轮流执行;restart |
android:startOffset | 动画延迟执行的时间,单位是毫秒 |
插值器
插值器 | xml中的值 | 效果 |
---|---|---|
AccelerateDecelerateInterpolator | @android:anim/accelerate_decelerate_interpolator | 加速减速插值器 动画先加速再减速 |
AccelerateInterpolator | @android:anim/accelerate_interpolator | 加速插值器 动画速度越来越快 |
DecelerateInterpolator | @android:anim/decelerate_interpolator | 减速插值器 动画速度越来越慢 |
BounceInterpolator | @android:anim/bounce_interpolator | 回弹插值器 动画结束会回弹几下 |
CycleInterpolator | @android:anim/cycle_interpolator | 圆插值器,动画会重复几次,动画的速度沿着正弦曲线变化 |
LinearInterpolator | @android:anim/linear_interpolator | 线性插值器 动画速度保持匀速 |
AnticipateOvershootInterpolator | @android:anim/anticipate_overshoot_interpolator | 预期预期超调插值器。先往前甩一定的值,然后开始动画,结束时往后甩一定的值,结束动画。 |
AnticipateInterpolator | @android:anim/anticipate_interpolator | 预期插值器,动画开始时会往前甩一下 |
OvershootInterpolator | @android:anim/overshoot_interpolator | 超调插值器 动画结束时往后甩一下 |
具体使用
在xml中或者java代码中。
Translate:
xml初始化
<!--
以下参数是4种动画效果的公共属性,即都有的属性
android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
android:startOffset ="1000" // 动画延迟开始时间(ms)
android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
以下参数是平移动画特有的属性
android:fromXDelta="0" // 视图在水平方向x 移动的起始值
android:toXDelta="100%" // 视图在水平方向x 移动的结束值
android:fromYDelta="0" // 视图在竖直方向y 移动的起始值
android:toYDelta="500" // 视图在竖直方向y 移动的结束值
-->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:startOffset ="10"
android:fillBefore = "true"
android:fillAfter = "false"
android:fillEnabled= "false"
android:repeatMode= "restart"
android:repeatCount = "0"
android:interpolator = "@android:anim/bounce_interpolator"
android:fromXDelta="0"
android:toXDelta="100%"
android:fromYDelta="0"
android:toYDelta="100%"/>
//在class中使用:
translateAnimation = AnimationUtils.loadAnimation(this,R.anim.anim_translate)
btn.startAnimation(translateAnimation)
java代码初始化:
~~~
fun initTraslateForCode() : Animation{
//绝对坐标
// translateAnimation = TranslateAnimation(0F,100F,0F,100F)
//绝对坐标
// translateAnimation = TranslateAnimation(Animation.ABSOLUTE,0F,Animation.ABSOLUTE,150F,Animation.ABSOLUTE,0F,Animation.ABSOLUTE,150F)
//相对于自己的百分比坐标
translateAnimation = TranslateAnimation(Animation.RELATIVE_TO_SELF,0F,Animation.RELATIVE_TO_SELF,100F,Animation.RELATIVE_TO_SELF,0F,Animation.RELATIVE_TO_SELF,100F)
//相对于ParentView的百分比坐标
// translateAnimation = TranslateAnimation(Animation.RELATIVE_TO_PARENT,0F,Animation.RELATIVE_TO_PARENT,100F,Animation.RELATIVE_TO_PARENT,0F,Animation.RELATIVE_TO_PARENT,100F)
translateAnimation.duration = 3000
return translateAnimation
}
~~~
TranslateAnimation独有属性
TranslateAnimation独有属性 | 含义 |
---|---|
android:fromXDelta | 动画开始时View左上角的X坐标,也有三种写法: 数值:50;百分数:50%;百分数p:50%p。 如果是数值,表示以View的左上角为(0,0),然后加上写的数值,以这个点作为开始点。 如果为百分数,如50%,表示总左上角(0,0)加上自身高度的50%, 作为开始点。 如果是百分数p,如50%p,表示总左上角(0,0)加上父控件高度的50%,作为开始点。 |
android:fromYDelta | 动画开始时View左上角的Y坐标,也有三种写法 |
android:toXDelta | 动画结束时View左上角的X坐标,也有三种写法 |
android:toYDelta | 动画结束时View左上角的Y坐标,也有三种写法 |
Scale:
ScaleAnimation独有属性:
ScaleAnimation独有属性 | 含义 |
---|---|
android:pivotX | float,缩放起点,或缩放原点的X轴坐标。 缩放围绕这个点运行。 这个坐标默认是View的左上角,(0,0) 在XML中的值有三种写法. |
android:pivotY | float,同上 Y轴坐标. 在XML中的值有三种写法 |
android:fromXScale | float 动画开始时,X轴上缩放的比例。1表示本身大小。 |
android:fromYScale | float 动画开始时,Y轴上缩放的比例。1表示本身大小。 |
android:toXScale | float Y动画结束时,X轴上缩放的比例。1表示本身大小。 |
android:toYScale | float Y动画结束时,Y轴上缩放的比例。1表示本身大小。 |
Rotate Rotate独有属性:
RotateAnimation独有属性 | 含义 |
---|---|
android:pivotX | 旋转动画的中心的X坐标,旋转围绕这个点进行,也有三种写法, |
android:pivotY | 旋转动画的中心的Y坐标,旋转围绕这个点进行,也有三种写法 |
android:fromDegrees | 动画开始时的旋转角度。角度顺时针转增加,逆时针转减少。 所以根据开始角度和结束角度来判断是顺时针还是逆时针。360度为一圈。 |
android:toDegrees | 动画结束时的旋转角度。 |
Alpha Alpha独有属性:
AlphaAnimation的独有属性 | 含义 |
---|---|
android:fromAlpha | 动画开始时的透明度 从0.0-1.0 0.0表示完全透明,1.0表示完全不透明 |
android:toAlpha | 动画结束时的透明度 |
set组合动画
//anim_set.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000">
<rotate
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="360"
android:toDegrees="-90"
/>
<alpha
android:fromAlpha="1"
android:toAlpha="0.2"/>
</set>
//java
Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.set);
// 步骤2:创建 动画对象 并传入设置的动画效果xml文件
mButton.startAnimation(translateAnimation);
java代码设置:
// 组合动画设置
AnimationSet setAnimation = new AnimationSet(true);
// 步骤1:创建组合动画对象(设置为true)
// 步骤2:设置组合动画的属性
// 特别说明以下情况
// 因为在下面的旋转动画设置了无限循环(RepeatCount = INFINITE)
// 所以动画不会结束,而是无限循环
// 所以组合动画的下面两行设置是无效的
setAnimation.setRepeatMode(Animation.RESTART);
setAnimation.setRepeatCount(1);// 设置了循环一次,但无效
// 步骤3:逐个创建子动画(方式同单个动画创建方式)
// 子动画1:旋转动画
Animation rotate = new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotate.setDuration(1000);
rotate.setRepeatMode(Animation.RESTART);
rotate.setRepeatCount(Animation.INFINITE);
// 子动画2:平移动画
Animation translate = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT,-0.5f,
TranslateAnimation.RELATIVE_TO_PARENT,0.5f,
TranslateAnimation.RELATIVE_TO_SELF,0
,TranslateAnimation.RELATIVE_TO_SELF,0);
translate.setDuration(10000);
// 子动画3:透明度动画
Animation alpha = new AlphaAnimation(1,0);
alpha.setDuration(3000);
alpha.setStartOffset(7000);
// 子动画4:缩放动画
Animation scale1 = new ScaleAnimation(1,0.5f,1,0.5f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
scale1.setDuration(1000);
scale1.setStartOffset(4000);
// 步骤4:将创建的子动画添加到组合动画里
setAnimation.addAnimation(alpha);
setAnimation.addAnimation(rotate);
setAnimation.addAnimation(translate);
setAnimation.addAnimation(scale1);
动画的监听 补间动画只需设置开始视图和结束视图,中间的动画过程由系统完成,因此智能监听器开始和结束状态。
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Log.i(TAG, "动画开始时做操作: ");
}
@Override
public void onAnimationEnd(Animation animation) {
Log.i(TAG, "动画重复时做操作: ");
}
@Override
public void onAnimationRepeat(Animation animation) {
Log.i(TAG, "动画结束时做操作: ");
}
});
补充:ListView可以设置出场动画
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical" >
<ListView
android:id="@+id/listView1"
android:layoutAnimation="@anim/anim_layout"
// 指定layoutAnimation属性用以指定子元素的入场动画
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
逐帧动画
作用对象 视图控件(View)
1.如Android的TextView、Button等等
2.不可作用于View组件的属性,如:颜色、背景、长度等等
原理
- 将动画拆分为 帧 的形式,且定义每一帧 = 每一张图片
- 逐帧动画的本质:按序播放一组预先定义好的图片
具体使用 xml:
//knight_attack.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true" // 设置是否只播放一次,默认为false>
// item = 动画图片资源;duration = 设置一帧持续时间(ms)
<item android:drawable="@drawable/a0" android:duration="100"/>
<item android:drawable="@drawable/a1" android:duration="100"/>
<item android:drawable="@drawable/a2" android:duration="100"/>
<item android:drawable="@drawable/a3" android:duration="100"/>
<item android:drawable="@drawable/a4" android:duration="100"/>
<item android:drawable="@drawable/a5" android:duration="100"/>
<item android:drawable="@drawable/a6" android:duration="100"/>
<item android:drawable="@drawable/a7" android:duration="100"/>
<item android:drawable="@drawable/a8" android:duration="100"/>
<item android:drawable="@drawable/a9" android:duration="100"/>
<item android:drawable="@drawable/a10" android:duration="100"/>
<item android:drawable="@drawable/a11" android:duration="100"/>
<item android:drawable="@drawable/a12" android:duration="100"/>
<item android:drawable="@drawable/a13" android:duration="100"/>
<item android:drawable="@drawable/a14" android:duration="100"/>
<item android:drawable="@drawable/a15" android:duration="100"/>
<item android:drawable="@drawable/a16" android:duration="100"/>
<item android:drawable="@drawable/a17" android:duration="100"/>
<item android:drawable="@drawable/a18" android:duration="100"/>
<item android:drawable="@drawable/a19" android:duration="100"/>
<item android:drawable="@drawable/a20" android:duration="100"/>
<item android:drawable="@drawable/a21" android:duration="100"/>
<item android:drawable="@drawable/a22" android:duration="100"/>
<item android:drawable="@drawable/a23" android:duration="100"/>
<item android:drawable="@drawable/a24" android:duration="100"/>
<item android:drawable="@drawable/a25" android:duration="100"/>
</animation-list>
//java 代码:
iv.setImageResource(R.drawable.knight_attack);
// 1. 设置动画
animationDrawable = (AnimationDrawable) iv.getDrawable();
// 2. 获取动画对象
animationDrawable.start();
在Java代码中实现:
animationDrawable = new AnimationDrawable();
for (int i = 0; i <= 25; i++) {
int id = getResources().getIdentifier("a" + i, "drawable", getPackageName());
Drawable drawable = getResources().getDrawable(id);
animationDrawable.addFrame(drawable, 100);
}
animationDrawable.setOneShot(true);
iv.setImageDrawable(animationDrawable);
// 获取资源对象
animationDrawable.stop();
// 特别注意:在动画start()之前要先stop(),不然在第一次动画之后会停在最后一帧,这样动画就只会触发一次
animationDrawable.start();
// 启动动画
作者:Carson_Ho
链接:https://www.jianshu.com/p/225fe1feba60
注意
尽量避免使用尺寸较大的图片,否则会引起oom
属性动画
补间动画的局限性:
1.作用对象有局限性,只能作用在View上,无法对view的属性进行动哈操作;
2.没有改变View的属性,只是改变视觉效果;
3.效果单一,智能实现平移,选择,缩放,透明度4中或者这4种组合的动画
属性动画的原理
在一定时间间隔内,通过不断对值进行改变,并不断将该值赋给对象的属性,从而实现该对象在该属性上的动画效果
ValueAnimation
- ValueAnimator.ofInt(int values)
将初始值 以整型数值的形式 过渡到结束值,即使整型估值器 - IntEvalutor
private void initValueAnimator() {
// ofInt()作用有两个
// 1. 创建动画实例
//2. 将传入的多个Int参数进行平滑过渡:此处传入0和1,表示将值从0平滑过渡到1
// 如果传入了3个Int参数 a,b,c ,则是先从a平滑过渡到b,再从b平滑过渡到C,以此类推
// ValueAnimator.ofInt()内置了整型估值器,直接采用默认的.不需要设置,即默认设置了如何从初始值 过渡到 结束值
final ValueAnimator valueAnimator = ValueAnimator.ofInt(0,3);
// 步骤2:设置动画的播放各种属性
valueAnimator.setDuration(500);
// 设置动画延迟播放时间
valueAnimator.setStartDelay(500);
// 设置动画重复播放次数 = 重放次数+1
// 动画播放次数 = infinite时,动画无限重复
valueAnimator.setRepeatCount(0);
// 设置重复播放动画模式
// ValueAnimator.RESTART(默认):正序重放
// ValueAnimator.REVERSE:倒序回放
valueAnimator.setRepeatMode(ValueAnimator.RESTART);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int currentValue = (int) animation.getAnimatedValue();
Log.i("ValueAnimator:" , currentValue +"");
//todo 将值赋值给View的某个绘制属性,并重新绘制View。
}
});
valueAnimator.start();
}
结果为:
05-10 22:06:44.078 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.094 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.115 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.133 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.151 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.169 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.187 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.204 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.224 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.241 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 0
05-10 22:06:44.258 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.276 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.294 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.312 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.331 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.347 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.366 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 1
05-10 22:06:44.386 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.405 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.423 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.440 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.459 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.476 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.493 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.511 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.530 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.548 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 2
05-10 22:06:44.567 4618-4618/com.aoyj.animaiton.valueanimationmaster I/ValueAnimator:: 3
可以将动画写在在xml中,但是这样子value的初始值和结束值都时事先固定的。
//set_anim.xml
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0" // 初始值
android:valueTo="100" // 结束值
android:valueType="intType" // 变化值类型 :floatType & intType
android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
android:startOffset ="1000" // 动画延迟开始时间(ms)
android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
/>
//在java代码中使用
ValueAnimator valueAnimator = ValueAnimatorInflater.loadAnimator(context,R.anim.set_anim);
valueAnimator.start();
作者:Carson_Ho
链接:https://www.jianshu.com/p/2412d00a0ce4
來源:简书
***ValueAnimator.ofFloat()***
与ValueAnimator.ofiInt()类似
ValueAnimator.ofObject()
ValueAnimator.ofInt()与ValueAnimator.ofFloat()都有内置的估值器,ValueAnimator.ofFloat()的估值器FloatEvaluetor实现为:
public class FloatEvaluator implements TypeEvaluator {
// FloatEvaluator实现了TypeEvaluator接口
// 重写evaluate()
public Object evaluate(float fraction, Object startValue, Object endValue) {
// 参数说明
// fraction:表示动画完成度(根据它来计算当前动画的值)
// startValue、endValue:动画的初始值和结束值
float startFloat = ((Number) startValue).floatValue();
return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
// 初始值 过渡 到结束值 的算法是:
// 1. 用结束值减去初始值,算出它们之间的差值
// 2. 用上述差值乘以fraction系数
// 3. 再加上初始值,就得到当前动画的值
}
}
对于ValueAnimator.ofObject(),我自定义Evaluetor
public class ObjectEvaluetor implements TypeEvaluetor{
@Override
public Object evaluetor(float fraction,Object startValue,Object endValue){
//fraction 为执行动画的完成度
//startValue endValue为初始值和结束值
... //计算对象动画的值
return value;
}
}
ValueAnimator.ofObject()总结:
ValueAnimator.ofObject()本质还是改变值,只是其可以同时改变一个对象的多个属性值。而ValueAnimator.ofInt()和ValueAnimator.ofFloat()只能改变一个值。
ObjectAnimator
ObjectAnimato和ValueAnimator本质都是通过不断改变View的某个值达到动画效果。不同的是
ValueAnimator是手动给View的某个属性赋值,而ObjectAnimator是自动给View的属性赋值。
和ValueAnimator类似,ObjectAnimator也有ObjectAnimator.ofInt(),ObjectAnimator.ofFloat(),ObjectAnimator.ofObject()这些类型,具体使用哪种要根据设置的property决定。
具体使用
java设置:
/**
Object object:需要操作的对象
String property:需要操作的对象的属性
float ....values:动画初始值 & 结束值(不固定长度)
若是两个参数a,b,则动画效果则是从属性的a值到b值
若是三个参数a,b,c,则则动画效果则是从属性的a值到b值再到c值
**/
ObjectAnimator animator = ObjectAnimator.ofFloat(Object object, String property, float ....values);
// 设置动画运行的时长
anim.setDuration(500);
// 设置动画延迟播放时间
anim.setStartDelay(500);
// 设置动画重复播放次数 = 重放次数+1,动画播放次数 = infinite时,动画无限重复
anim.setRepeatCount(0);
// 设置重复播放动画模式:RESTART(默认):正序重放,REVERSE:倒序回放
anim.setRepeatMode(ValueAnimator.RESTART);
缩放:
//缩放 java代码
fun initAnimator(){
//作用对象是btn
//作用的对象属性是x轴缩放
//动画效果是放大到3倍,在缩小到初始值
scaleAnimator = ObjectAnimator.ofFloat(btn,"scaleX",1f,3f,2f)
scaleAnimator.duration = 2000
scaleAnimator.start()
}
//xml scale_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="1"
android:valueType="floatType"
android:propertyName="scaleX"
android:valueTo="3"
android:repeatCount="0"
android:repeatMode="restart"
android:startOffset="100"
android:duration="500">
</objectAnimator>
//java代码中使用xml:
ObjectAniamtor scaleAnimator = ValueAnimatorInflater.loadAnimator(context,R.animtor.scale_animator) as ObjectAnimator
scaleAnimator.target = btn
scaleAnimator.start()
透明度:
//java代码:
fun initAnimator(){
alphaAnimator = ObjectAnimator.ofFloat(btn,"alpha",1f,0f,0.5f,1f)
alphaAnimator.duration = 500
alphaAnimator.repeatCount = 0
alphaAnimator.repeatMode = ValueAnimator.RESTART
alphaAniamtor.start()
}
//xml代码:alpha_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="1"
android:valueTo="0.5"
android:valueType="floatType"
android:propertyName="alpha"
android:duration="500"
android:startOffset="100"
android:repeatMode="restart"
android:repeatCount="0">
</objectAnimator>
//java 代码:
alphaAnimator = AnimatorInflater.loadAnimator(context,R.animator.alpha_animator) as ObjectAnimator
alphaAnimator.target = btn
alphaAnimator.start()
旋转
//java 代码
fun initAnimator(){
rotationAnimator = ObjectAnimator.ofFloat(btn,"rotation",0f,360f)
rotationAnimator.duration = 500
rotationAnimator.startDelay = 100
rotationAnimator.repeatMode = ValueAnimator.RESTART
rotationAnimator.repeatCount = 0
rotationAniamtor.start()
}
//xml代码:rotation_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType"
android:propertyName="rotation"
android:duration="500"
android:startOffset="100"
android:repeatCount="0"
android:repeatMode="reverse">
</objectAnimator>
//java 应用xml代码
rotationAnimator = AnimatorInflater.loadAnimator(context,R.animator.rotation_animator) as ObjectAnimator
rotationAnimator.target = btn
rotationAnimator.start()
平移:平移的坐标系都是以执行动画的View的左上角坐标点为起始点坐标
//java代码:
fun initAnimator(){
translateAnimator = ObjectAnimator.ofFloat(btn,"translationX",100F,200F)
translateAnimator.duration = 500
translateAnimator.interpolator = BounceInterpolator()
translationAnimator.start()
}
//xml 代码
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="500"
android:valueType="floatType"
android:propertyName="translationX"
android:interpolator="@android:anim/bounce_interpolator"
android:duration="500"
android:startOffset="100"
android:repeatMode="restart"
android:repeatCount="0">
</objectAnimator>
//java 应用xml代码
fun initAniamtorFromXml(){
translateAnimator = AnimatorInflater.loadAnimator(this,R.animator.translation_animator) as ObjectAnimator
translateAnimator.target = btn
translateAnimator.start()
}
ObjectAnimator在一般View上起作用的集中属性:
View属性值 | 效果 | 数值类型 |
---|---|---|
alpha | 控制透明度 | float |
translationX | 控制x方向上位移 (以执行动画的View的左上角为坐标原点) |
float(例如:0到50) |
translationY | 控制y方向上位移 (以执行动画的View的左上角为坐标原点) |
float(例:如0到500) |
scaleX | 控制x方向的缩放倍数 (个人认为以View的中心左边点为缩放点) |
float(例如:1到3) |
scaleY | 控制y方向的缩放倍数 (个人认为以View的中心左边点为缩放点) |
float(例如:1到3) |
rotation | 以屏幕方向为轴的旋转 | float(例如:0到360) |
rotationX | 以x轴方向旋转 | float(例如:0到360) |
rotationY | 以y轴方向旋转 | float(例如:0到360) |
AnimatorSet组合动画
AnimatorSet.play(Animator anim) :播放当前动画
AnimatorSet.after(long delay) :将现有动画延迟x毫秒后执行
AnimatorSet.with(Animator anim) :将现有动画和传入的动画同时执行
AnimatorSet.after(Animator anim) :将现有动画插入到传入的动画之后执行
AnimatorSet.before(Animator anim) : 将现有动画插入到传入的动画之前执行
xml:
//set_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially" >
// 表示Set集合内的动画按顺序进行
// ordering的属性值:sequentially & together
// sequentially:表示set中的动画,按照先后顺序逐步进行(a 完成之后进行 b )
// together:表示set中的动画,在同一时间同时进行,为默认值
<set android:ordering="together" >
// 下面的动画同时进行
<objectAnimator
android:duration="2000"
android:propertyName="translationX"
android:valueFrom="0"
android:valueTo="300"
android:valueType="floatType" >
</objectAnimator>
<objectAnimator
android:duration="3000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType" >
</objectAnimator>
</set>
<set android:ordering="sequentially" >
// 下面的动画按序进行
<objectAnimator
android:duration="1500"
android:propertyName="alpha"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType" >
</objectAnimator>
<objectAnimator
android:duration="1500"
android:propertyName="alpha"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" >
</objectAnimator>
</set>
</set>
android 动画框架
LayoutAnimation
LayoutAnimation是应用于ViewGroup的动画框架。它可以使VeiwGroup中的childView按照绘制先后,顺序执行动画。
java代码设置
//具体执行的animation:
//animation_layout_scale.xml
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:pivotY="50%"
android:pivotX="50%"
android:fromYScale="0.1"
android:fromXScale="0.1"
android:toXScale="1"
android:toYScale="1">
</scale>
//初始化LayoutAnimationControl
Animation animation = AnimationUtils.loadAnimation(mContext,R.anim.animation_layout_scale);
//第一个参数是具体执行的动画,第二个参数是layoutAnimation的延时百分比
LayoutAnimationController controller = new LayoutAnimationControl(animation,0.3f);
//设置动画执行顺序
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
listVeiw.setlayoutAnimation(controller);
xml实现:
//layout_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="0.3"
android:animationOrder="normal"
android:animation="@anim/animation_layout_scale">
</layoutAnimation>
//Viewgroup设置LayoutAnimation属性
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layoutAnimation="@anim/layout_animation"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>
delay:指的是child view相对于上一个childView动画的延时时间。取值是具体执行的animation的动画时间的倍数;
animationOrder:指的是ViewGroup中child view动画开始的顺序。normal(按照正常的绘制顺序执行),reverse(按照绘制顺序逆序执行),random(随机执行);
animation:child view具体执行的动画,只能是补间动画;
ViewAnimationUtils
android 5.0以上的生成一个圆形动画的animator;
private void startViewAniamtionUtils(){
int centreX = btn.getWidth();
int centreY = btn.getHeight();
float hypot = (float) Math.hypot(btn.getHeight(), btn.getWidth());
//第一个参数是执行圆形动画的view,第二,第三个参数是圆心,第四,第五个参数是圆的半径取值范围
Animator animator = ViewAnimationUtils.createCircularReveal(btn,centreX,centreY,0,hypot);
animator.setDuration(600);
animator.setStartDelay(10);
// animator.setInterpolator(new LinearInterpolator());
AnimatorSet set = new AnimatorSet();
set.play(animator)
.with(getAlphAnimator());
set.setDuration(600);
set.setInterpolator(new AccelerateInterpolator());
set.start();
}
private ObjectAnimator getAlphAnimator(){
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(btn,"alpha",0f,1f);
objectAnimator.setDuration(600);
objectAnimator.setTarget(btn);
// objectAnimator.setInterpolator(new LinearInterpolator());
return objectAnimator;
}
overridePendingTransition
指定Activity的退出和进入动画,它包括两个部分
一部分是第一个activity退出时的动画,
另外一个部分是第二个activity进入时的动画。
需要注意两个部分:
- 在android2.0以上调用,
- 要在startActivity或者finished的后面调用。
@OnClick(R.id.button)
public void onViewClicked() {
finish();
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
}
//enter_anim:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="-30%"
android:toXDelta="0">
</translate>
//exit_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="0"
android:toXDelta="100%">
</translate>
ViewPropertyAnimator
本质上和ValueAniamtor和ObjectAnimator相同,能够很方便的为view提供动画。
button2.animate()
.translationXBy(200)
//.translationX(200)
.setDuration(500);
ViewProperty中带by的方法含义是,相对于执行动画View的现有状态进行动画,不带by的方法含义是相对于View最初始状态进行动画。translationXBy(200)每次执行动画,button2的位置都会相对于现有位置平移200px.translationX(200):不管执行多少次动画,button2的位置都是相对于初始位置平移200px,换句话说button2会在第一次执行动画时平移200px,后面执行动画,button2的位置不会发生变化。
SpringAniamtion
这是弹簧动画;
SpringForce spring = new SpringForce(0)
.setDampingRatio(SpringForce.DAMPING_RATIO_HIGH_BOUNCY)
.setStiffness(SpringForce.STIFFNESS_LOW);
new SpringAnimation(rootLayout, DynamicAnimation.TRANSLATION_Y)
.setSpring(spring)
.setStartValue(-height)
.setStartVelocity(-200)
.start();
SpringAniamtion可以实现旋转,平移,缩放,透明度等的动画。
- setDampingRatio():设置阻尼系数,取值范围在0 ~ 1之间,值越大弹簧效果越明显。
- setStiffness(): 设置刚性,取值范围在0 ~ 1之间。值越小,弹簧震动次数也多。