安卓动画全解:补间动画(视图动画)、布局动画、属性动画、逐帧动画。动画Animation属性、Alpha属性、Scale属性、Translate属性、Rotate属性,动画集AnimationSet
全栈工程师开发手册 (作者:栾鹏)
安卓动画全解:补间动画(视图动画)、布局动画、属性动画、逐帧动画。
主要内容包含:动画Animation属性、Alpha属性、Scale属性、Translate属性、Rotate属性,动画集AnimationSet,动画的两种定义形式(xml中定义和java中定义),应用两种形式的动画和应用动画集。
动画的属性
Animation的属性
JAVA方法 XML属性 解释
setDetachWallpaper(boolean) android:detachWallpaper 是否在壁纸上运行
setDuration(long) android:duration 设置动画持续时间,单位为毫秒
setFillAfter(boolean) android:fillAfter 控件动画结束时控件是否保持动画最后状态
setFillBefore(boolean) android:fillBefore 控件动画结束时控件是否还原到开始动画前的状态
setFillEnable(boolean) android:fillEnable(boolean) 与android:fillBefore效果相同
setInterpolator(boolean) android:interpolator 设置插值器(指定的动画效果,如:回弹等)
setRepeatCount(int) android:repeatCount 重复次数
setRepeatMode(int) android:repeatMode 重复类型:reverse倒序回放、restart从头播放
setStartOffset(long) android:startOffset 调用start函数后等待开行运行的时间,单位为毫秒
setZadjustment(int) android:zAdjustment 表示被设置动画的内容运行时在Z轴的位置(top/bottom/normal),默认为normal
由于Animation类是其抽象父类,那么我们在使用补间动画无论是哪一种都已经具备了以上属性。
下面是每一种补间动画的特有属性:
Alpha属性
JAVA方法 XML属性 解释
AlphaAnimation(float fromAlpha,…) android:fromAlpha 动画开始的透明度(0.0到1.0,0.0是全透明,1.0是不透明)
AlphaAnimation(…, float toAlpha) androdi:toAlpha 动画结束的透明度(同上)
Rotate属性
JAVA方法 XML属性 解释
RotateAnimation(float fromDegrees, …) android:fromDegress 旋转开始角度,正代表顺时针度数,负代表逆时针度数
RotateAnimation(…, float toDegress) android:toDegress 旋转结束角度(同上)
RotateAnimation(…, …, float pivotX, …) android:pivotX 缩放起点X坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)
RotateAnimation(…, …, …, pivotY) android:pivotY 缩放起点Y坐标(同上)
Scale属性
JAVA方法 XML属性 解释
ScaleAnimation(float fromX, …) android:fromXScale 初始X轴缩放比例,1.0表示无变化
ScaleAnimation(…, float toX) android:toXScale 结束X轴缩放比例
ScaleAnimation(…, …, float fromY, …) androd:fromYScale 初始Y轴缩放比例
ScaleAnimation(…, …, …, float toY) android:toYScale 结束Y轴缩放比例
ScaleAnimation(…, float pivotX, …) android:pivotX 缩放起点X轴坐标(同上)
ScaleAnimation(…, float pivotY) android:pivotY 缩放起点Y轴坐标(同上)
Translate属性
JAVA方法 XML属性 解释
TranslateAnimation(float fromXDelta, …) android:fromXDelta 平移起始点X轴坐标
TranslateAnimation(…, float toXDelta) android:toXDelta 平移结束点X轴坐标
TranslateAnimation(…, float fromYDelta, …) android:fromYDelta 平移起始点Y轴坐标
TranslateAnimation(…, float toYDelta) android:toYDelta 平移结束点Y轴坐标
AnimationSet属性
AnimationSet类比较特殊,因为该类是以上4类的组合容器管理类,没有自己特有的属性,它的属性继承自它的父类:Animation。
我们在使用的时候需要注意,当我们在对set标签设置属性的时候,那么其标签下的所有控件都会产生影响。
补间动画(视图动画):
补间view动画(改变外观,不改变属性):窗口间切换、窗口内布局间的切换、相同view的不同内容间的切换、向用户提供反馈(进度、晃动)
定义、应用补间动画(视图动画)的形式
动画的定义有两种形式,一种是在xml中设计动画,一种是在java中设计动画。
1、在res/anim下定义一个补间动画文件popin.xml
<?xml version="1.0" encoding="utf-8" ?>
<!-- 补间view动画(改变外观,不改变属性):窗口间切换、窗口内布局间的切换、相同view的不同内容间的切换、向用户提供反馈(进度、晃动) -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<!-- 定义一个差值view动画 -->
<scale
android:fromXScale="1.0" android:toXScale="0.0"
android:fromYScale="1.0" android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="10"
android:repeatMode="reverse"
android:duration="1000" />
</set>
<!--
设置每一个子动画的开始偏移时间和持续时间很重要,否则就会同时开始和结束
动画可设置的属性,已在前面给出
-->
2、在代码中应用xml中定义的补间动画
Animation myanimation = AnimationUtils.loadAnimation(context, R.anim.popin);
myanimation.setRepeatMode(Animation.REVERSE); //设置动画模式,RESTART动画正向,REVERSE动画反向
myanimation.setRepeatCount(500); //设置动画循环次数,Animation.INFINITE无限次,对于xml中的动画,这个属性必须在xml中设置才有效
myanimation.setAnimationListener(new AnimationListener() { //设置动画监听器
@Override
public void onAnimationStart(Animation animation) {
//动画开始时执行处理
Log.v("补间动画", "动画开始");
}
@Override
public void onAnimationRepeat(Animation animation) {
//动画重复时执行处理
Log.v("补间动画", "动画重复");
}
@Override
public void onAnimationEnd(Animation animation) {
//动画完成后执行处理
Log.v("补间动画", "动画结束"); //最后一遍动画结束
}
});
//应用动画
TextView tv = (TextView) findViewById(R.id.activity1_text1);
tv.startAnimation(myanimation); //应用动画到控件
3、在java代码中应用自定义补间动画
下面简单介绍了透明动画,旋转动画,缩放动画,位移动画。动画可设置的属性已在前面给出。
//自定义透明度动画
public void alpha(View v){
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(1000);
anim.setRepeatCount(10);
v.startAnimation(anim);
}
//自定义旋转动画
public void rotate(View v){
RotateAnimation anim = new RotateAnimation(0.0f, -360f, v.getWidth()/2, v.getHeight()/2);
anim.setDuration(1000);
v.startAnimation(anim);
}
//自定义缩放动画
public void scale(View v){
ScaleAnimation anim = new ScaleAnimation(1.0f, 0.0f, 0.0f, 1.0f, v.getWidth() / 2, v.getHeight() / 2);
anim.setDuration(1000);
v.startAnimation(anim);
}
//自定义位移动画
public void translate(View v){
TranslateAnimation anim = new TranslateAnimation(0.0f, 10.0f, 100f, 200f);
anim.setDuration(1000);
v.startAnimation(anim);
}
应用补间动画合集
我们知道如何设置和应用xml中的动画和java中自定义动画后,我们就可以来为控件或布局应用动画合集了。
在动画合集中可以添加xml中的动画,也可以添加java代码中设计的动画。
//应用动画集合
public void animationset(View v) {
AnimationSet animationSet = new AnimationSet(true);
Animation anim1 = AnimationUtils.loadAnimation(context, R.anim.popin);
AlphaAnimation anim2 = new AlphaAnimation(0.0f, 1.0f);
anim2.setDuration(1000);
anim2.setRepeatCount(10);
animationSet.addAnimation(anim1);
animationSet.addAnimation(anim2);
v.startAnimation(animationSet); //应用动画集合
}
布局动画
布局动画,可以用来为View Group添加动画,按照预定的顺序和一个动画或动画集合应用到viewGroup的每一个子view中
应用布局动画也有两种形式。
1、一种是在res/anim下只创建补间动画的xml,如上面的popin.xml,然后在java中将这种补间动画,转化为布局动画应用到View Group
//应用布局动画,应用到viewgroup中
public void apply_layoutanimation(ViewGroup view) {
//通过加载XML动画设置文件来创建一个Animation对象;
Animation anim=AnimationUtils.loadAnimation(this, R.anim.popin);
//得到一个LayoutAnimationController对象;
LayoutAnimationController controller=new LayoutAnimationController(anim);
//设置控件显示的顺序;
controller.setOrder(LayoutAnimationController.ORDER_REVERSE); //对于
//设置每个控件动画的间隔时间,单位秒;
controller.setDelay(0.3f);
//为View Group设置LayoutAnimationController属性;
view.setLayoutAnimation(controller);
}
2、另一种方式处理在res/anim下创建补间动画的xml,还在res/anim下创建布局动画的xml,然后在UI的xml中应用布局动画。这里除了上面的popin.xml,再创建一个popinlayout.xml的布局动画
<?xml version="1.0" encoding="utf-8" ?>
<!-- 布局动画,可以用来为View Group添加动画,按照预定的顺序和一个动画或动画集合应用到viewGroup的每一个子view中 -->
<layoutAnimation
xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="0.3"
android:animationOrder="random"
android:animation="@anim/popin"
/>
<!--
Android:delay 子类动画时间间隔 (延迟) 70% 也可以是一个浮点数 如“1.2”等
android:animationOrder="random" 子类的显示方式 normal 0 默认,reverse 1 倒序,random 2 随机
android:animation="@anim/slide_right" 表示子类显示时的具体动画是什么
其中delay的单位为秒;animation为设置动画的文件。animationOrder为进入方式
-->
布局动画的xml不能再Java中引入,必须在窗口的UI文件中引入使用
<?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:id="@+id/activity1_linearlayout1"
android:layoutAnimation="@anim/popinlayout" >
</LinearLayout>
逐帧动画
逐帧动画,选项图像顺序播放的功能。逐帧动画的xml文件存放在res/drawable文件夹下。
首先在res/drawable文件下建一个逐帧动画的anim3.xml文件
<?xml version="1.0" encoding="utf-8" ?>
<!-- 逐帧动画,选项图像顺序播放-->
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="@drawable/img1" android:duration="500" />
<item android:drawable="@drawable/img2" android:duration="500" />
<item android:drawable="@drawable/img3" android:duration="500" />
</animation-list>
<!--
在java中调用
imageView1.setBackgroundResource(R.drawable.anim3);
AnimationDrawable androidanimation = (AnimationDrawable)imageView1.getBackground();
androidanimation.start();
-->
在java中调用逐帧动画,并应用到ImageView中。逐帧动画只能放在ImageView中。
public void apply_animation_list(ImageView imageView) {
imageView.setBackgroundResource(R.drawable.anim3);
//通过实例控制动画运行
AnimationDrawable animation=(AnimationDrawable)imageView.getBackground();
animation.start(); //启动播放
//animation.stop(); //停止播放
}
属性动画
属性动画也有两种定义方式
1、在res/animator文件夹下定义属性动画的xml,这里命名为anim1.xml
<?xml version="1.0" encoding="utf-8" ?>
<!-- 属性动画 -->
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="alpha"
android:duration="1000"
android:valueFrom="0.0"
android:valueTo="1.0"
android:valueType="floatType"
android:repeatCount="-1"
android:repeatMode="reverse"
/>
<!--
可以设置动画集
<set android:ordering=["together" | "sequentially"]>
属性动画格式
<objectAnimator
android:propertyName="string"
android:duration="int"
android:valueFrom="float | int | color"
android:valueTo="float | int | color"
android:startOffset="int"
android:repeatCount="int"
android:repeatMode=["repeat" | "reverse"]
android:valueType=["intType" | "floatType"]/>
<animator
android:duration="int"
android:valueFrom="float | int | color"
android:valueTo="float | int | color"
android:startOffset="int"
android:repeatCount="int"
android:repeatMode=["repeat" | "reverse"]
android:valueType=["intType" | "floatType"]/>
<set />
</set>
-->
在java中应用在xml中定义的属性动画
public void apply_objectAnimator(View view)
{
//应用动画资源
Animator animation=AnimatorInflater.loadAnimator(context, R.animator.anim1);
animation.setDuration(500); //默认为300
animation.setTarget(view); //设置目标
//设置插值器
//AccelerateDecelerateInterpolator开始和结束时速度变换缓慢,在中间的时候加速
//AccelerateInterpolator开始时速度变化较慢,在中间的时候加速
//AnticipateInterpolator开始的时候向后,然后再向前急冲
//AnticipateOvershootInterpolator开始的时候向后,然后再向前急冲一定的值后,最后回到最终的值
//BounceInterpolator动画结束时弹起
//DecelerateInterpolator开始时速度变化较快,然后减速
//LinearInterpolator速度的变化是一个常量
//OvershootInterpolator开始向前急冲,超过最终的值,然后再回来
animation.setInterpolator(new LinearInterpolator());
//应用监听器
animation.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
Log.v("属性动画", "动画开始");
}
@Override
public void onAnimationRepeat(Animator animation) {
Log.v("属性动画", "动画重复");
}
@Override
public void onAnimationEnd(Animator animation) {
Log.v("属性动画", "动画结束");
}
@Override
public void onAnimationCancel(Animator animation) {
Log.v("属性动画", "动画取消");
}
});
animation.start(); //启动
}
2、在java中定义同时应用属性动画
public void apply_objectAnimator1(View view) {
ObjectAnimator animator1 =ObjectAnimator.ofFloat(view, "rotationX", 0.0F, 360.0F); //参数:控件,动画属性,起始状态,终止状态
ObjectAnimator animator2 =ObjectAnimator.ofFloat(view, "rotationX", 360.0F); //参数:控件,动画属性,终止状态(从当前状态开始)
animator1.setDuration(2000);
animator1.start();
//动画的属性和参数内容较多
//ObjectAnimator.ofFloat(view,"rotation",0,180,0); //中心旋转,0度到180度再到0度
//ObjectAnimator animator = ObjectAnimator.ofFloat(view,"rotationX",0,270,0); //中心轴为x轴的旋转,从0度到270度再到0度
//ObjectAnimator animator = ObjectAnimator.ofFloat(view,"rotationY",0,180,0); //中心轴为y轴的旋转,从0度到180度再到0度
//ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", 0, 200, -200,0); //当前位置向右200像素,再移动到距离原点左侧200的位置,最后回到原点;
//ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationY", 0, 200, -100,0); //当前位置向下200像素,再移动到距离原点上方200的位置,最后回到原点;
//ObjectAnimator animator = ObjectAnimator.ofFloat(view, "scaleX", 0, 3, 1); //横向上,从0倍放大到3倍,然后再还原到1倍的原始状态。
//ObjectAnimator animator = ObjectAnimator.ofFloat(view, "scaleY", 0, 3, 1); //纵向上,从0倍放大到3倍,然后再还原到1倍的原始状态。
}
应用属性动画集
属性动画集中也使用AnimatorSet,每一个动画可以是xml中定义的,也可以是java中定义的。要使用两次一个动画,需要创建两个动画对象。
public void animationset_object(View view) {
Animator animation1=AnimatorInflater.loadAnimator(context, R.animator.anim1); //获取xml中定义的动画
Animator animation2=AnimatorInflater.loadAnimator(context, R.animator.anim1); //一个动画可以多次使用
ObjectAnimator animation3 =ObjectAnimator.ofFloat(view, "rotationX", 360.0F); //java中自定义动画
animation1.setTarget(view); //设置目标
animation2.setTarget(view); //设置目标
AnimatorSet myset=new AnimatorSet();
myset.play(animation1).before(animation2); //设置前后顺序
myset.play(animation3).with(animation2); //同时播放,myset.playTogether(animation1, animation3);
myset.play(animation2).after(animation1); //设置前后顺序
myset.setDuration(1000); //设置周期
myset.start(); //启动动画集合
}
上一篇: vueRouter-路由的三种守卫
下一篇: Java编程用链表实现链式栈