今天花了一天时间学习了Android动画的一种——View Animation(视图动画),好记性不如烂笔头,赶紧写篇博客记录下吧!动画的使用是Android开发中常用的知识,今天就和大家一起了解下。知识点新鲜出炉,欢迎大家交流研讨!
本篇博客除了简单介绍Android动画知识外,还会通过示例代码(注释很详细哦)重点介绍Tween Animation(补间动画)的使用方法及特点。
Android中动画主要包括View Animation(视图动画)和Property Animation(属性动画,Android 3.0 后新增)两大类,其中View Animation又分为Tween Animation(补间动画)和Frame Animation( 帧动画),Tween Animation主要有AlphaAnimation(透明)、TranslateAnimation(平移)、RotateAnimation(旋转)和ScaleAnimation(缩放)4种。下图可以帮大家更快地了解Android动画的分类。
首先说下视图动画,顾名思义,View Animation只能应用于视图View上,而且只支持对整个视图进行操作,比如缩放旋转等。它并不改变View的属性,只是改变了View对象绘制的位置,并没有改变View对象本身。比如,你有一个屏幕左上角的Button,通过补间动画将其移动到右下角,动画过程中Button的可点击区域仍是左上角,因为实际上Button还是停留在屏幕左上角,补间动画知识改变了视觉效果而已。另外,它的动画效果单一,只能实现透明、平移、旋转和缩放这些简单的需求。
需要说明的是,Frame Animation(帧动画)也属于视图动画,但是动画效果和补间动画(透明、平移、旋转和缩放)不太一样,我们会在下一篇博客单独讨论。下面,我们一起来探讨下Tween Animation(补间动画)的使用。文中示例是对一个居中显示的图片进行操作,MainActivity的布局文件如下(算了,不贴代码了,放个截图吧,有时间自己敲一下咯)。另外,你需要知道:Android坐标系原点为左上角,X、Y轴分别向右、向下为正。
实现方式(补间动画均可以通过代码和Xml两种方式实现)。
代码方式
// 1.获取AlphaAnimation实例,传入起止透明度
// 设置起止透明度,取值范围0~1(透明~不透明)
float fromAlpha = 1.0f;
float toAlpha = 0.5f;
Animation animation = new AlphaAnimation(fromAlpha, toAlpha);
// 2.设置动画时长,单位为毫秒
animation.setDuration(3000);
// 3.其他可选设置,xml都有对应的属性
animation.setStartOffset(2000);// 设置动画开始延时,单位毫秒
animation.setFillAfter(true);// 设置动画结束后保留最后状态
animation.setRepeatCount(2);// 设置动画重复次数(默认为0,也就是说设置重复次数为n动画会播放n+1次),Animation.INFINITE无限播放
animation.setRepeatMode(Animation.REVERSE);// 设置重复时播放的模式,Animation.RESTART(1):顺序播放;Animation.REVERSE(2):逆序播放
// 设置为逆序播放时:首次顺序播放,第2次逆序播放,第3次顺序播放……
// 4.开始动画
mImageView.startAnimation(animation);
// XML方式实现
// loadAnimationFromXml(R.anim.view_animation_alpha);
Xml方式
右键res文件夹>New>Android Resource File>出现New Resource File对话框,File name自定义(如view_animation_alpha)、Resource Type选择Animation、Root element输入alpha(与动画效果对应),OK后res文件夹下自动创建了anim文件夹及其xml文件。
创建其他补间动画资源文件方式与此相同,后续不再赘述。
view_animation_alpha.xml代码如下,其中属性与代码方式设置一一对应,可对比理解:
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="1.0"
android:toAlpha="0.5"
android:duration="3000"
android:startOffset="2000"
android:fillAfter="true"
android:repeatCount="2"
android:repeatMode="reverse">
<!--fromAlpha和toAlpha取值范围0~1,0表示完全透明、1表示完全不透明-->
</alpha>
MainActivity调用代码如下:
/**
* 使用Xml生成动画
* @param animResourceID 动画资源ID(例如R.anim.view_animation_alpha)
*/
private void loadAnimationFromXml(int animResourceID) {
// 通过AnimationUtils.loadAnimation(Context context, @AnimRes int id)获取Animation实例
Animation animation = AnimationUtils.loadAnimation(this, animResourceID);
// ImageView开始动画传入上述Animation实例
mImageView.startAnimation(animation);
}
下面动图为不设置repeatCount和repeatMode的效果,动画播放完停留在最后状态,恢复到开始状态是动图循环造成的(摊手)。
可以看到,代码方式实现补间动画比较简单,基本流程如下:
(1)获取Animation实例;
(2)设置动画时间及其他属性(可选)
(3)通过View的startAnimation()方法开始动画
Xml方式可以实现和代码方式一样的动画效果,当需要改变动画效果时只需要改变Xml文件就行,可维护性更好些。但是有些动画属性是运行时才决定的,就只能用代码方式实现了。
代码方式
TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
// 传入起止位置相对于View原位置的X、Y绝对偏移
// 平移动画的起始点应为View的中心点,而不是左上角
// 1.获取TranslateAnimation实例,传入起止XY坐标(都是相对于View原位置的绝对偏移量)
float fromXDelta = 0f;// 开始时View相对于原位置的X偏移
float toXDelta = 400f;// 结束时View相对于原位置的X偏移
float fromYDelta = 0f;// 开始时View相对于原位置的Y偏移
float toYDelta = 400f;// 结束时View相对于原位置的Y偏移
// 此构造函数坐标Type为Animation.ABSOLUTE
Animation animation = new TranslateAnimation(fromXDelta, toXDelta, fromYDelta, toYDelta);
// 2.设置动画时长,单位为毫秒
animation.setDuration(3000);
// 3.开始动画
mImageView.startAnimation(animation);
// XML方式实现
// loadAnimationFromXml(R.anim.view_animation_translate1);
TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
int fromYType, float fromYValue, int toYType, float toYValue)
// 传入起止位置相对于View原位置的XY Type及偏移
这里需要传入的XYType,主要有3种(这里理解了下面就没问题了):
(1)Animation.ABSOLUTE:默认为此,表示绝对像素值(相当于Xml中数值不加后缀,如"0")
(2)Animation.RELATIVE_TO_PARENT:相对于父控件的百分比(相当于Xml中数值加%p后缀,如"50%p",p为parent的缩写)
(3)Animation.RELATIVE_TO_SELF:相对于自身(相当于Xml中数值加%后缀,如"200%")
// 1.获取TranslateAnimation实例,传入起止XY坐标及坐标类型
int fromXType = Animation.ABSOLUTE;// 绝对(相当于Xml中数值不加后缀,如"0")
float fromXDelta = 0f;// X从原位置开始
// float fromXDelta = mImageView.getX();// 由于ImageView设置了居中,要想从原位置开始动画就不能通过这种方式
int toXType = Animation.RELATIVE_TO_PARENT;// 相对于父布局(相当于Xml中数值加%p后缀,如"50%p",p为parent的缩写)
float toXDelta = 0.5f;// 结束时向右偏移为父布局宽度的一半
int fromYType = Animation.ABSOLUTE;// 绝对
float fromYDelta = 0f;
int toYType = Animation.RELATIVE_TO_SELF;// 相对于自身(相当于Xml中数值加%后缀,如"200%")
float toYDelta = 2f;// 结束时向下偏移自身高度的两倍
Animation animation = new TranslateAnimation(
fromXType, fromXDelta,
toXType, toXDelta,
fromYType, fromYDelta,
toYType, toYDelta);
// 2.设置动画时长,单位为毫秒
animation.setDuration(3000);
// 3.开始动画
mImageView.startAnimation(animation);
// XML方式实现
// loadAnimationFromXml(R.anim.view_animation_translate2);
Xml方式
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:toXDelta="400"
android:fromYDelta="0"
android:toYDelta="400"
android:duration="3000">
</translate>
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:toXDelta="50%p"
android:fromYDelta="0"
android:toYDelta="200%"
android:duration="3000">
<!--无后缀 = ABSOLUTE;% = RELATIVE_TO_SELF;%p = RELATIVE_TO_PARENT-->
</translate>
构造方法一效果(向右向下移动400个像素):
构造方法二效果(向右移动父布局的50%、向下移动自身的两倍):
代码方式
RotateAnimation(float fromDegrees, float toDegrees)// 此时旋转中心为View左上角
Animation animation = new RotateAnimation(0, 45);
animation.setDuration(3000);
mImageView.startAnimation(animation);
// XML方式实现
// loadAnimationFromXml(R.anim.view_animation_rotate1);
RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)// 指定旋转中心
Animation animation = new RotateAnimation(0, 45, mImageView.getWidth() / 2, mImageView.getHeight() / 2);
animation.setDuration(3000);
mImageView.startAnimation(animation);
// XML方式实现
// loadAnimationFromXml(R.anim.view_animation_rotate2);
RotateAnimation( float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)// 指定旋转中心及中心XY Type
Animation animation = new RotateAnimation(0, 45,
Animation.RELATIVE_TO_PARENT, 0.25f,
Animation.RELATIVE_TO_PARENT, 0.25f);
animation.setDuration(3000);
mImageView.startAnimation(animation);
// XML方式实现
// loadAnimationFromXml(R.anim.view_animation_rotate3);
Xml方式
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="45"
android:duration="3000">
</rotate>
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="45"
android:pivotX="50%"
android:pivotY="50%"
android:duration="3000">
</rotate>
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="45"
android:pivotX="25%p"
android:pivotY="25%p"
android:duration="3000">
</rotate>
构造方法一效果(以View左上角为旋转中心顺时针旋转45°):
构造方法二效果(以View中心点为旋转中心顺时针旋转45°):
构造方法三效果(以父布局1/4宽高为旋转中心顺时针旋转45°,本例中设置了ImageView居中,因此实际旋转中心为父布局3/4(1/2+1/4)宽高):
代码方式
ScaleAnimation(float fromX, float toX, float fromY, float toY)// 此时缩放基点为View左上角
Animation animation = new ScaleAnimation(1, 2, 1, 2);
animation.setDuration(3000);
mImageView.startAnimation(animation);
// XML方式实现
// loadAnimationFromXml(R.anim.view_animation_scale1);
ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY)// 指定缩放基点
Animation animation = new ScaleAnimation(1, 2, 1, 2, mImageView.getWidth() / 2, mImageView.getHeight() / 2);
animation.setDuration(3000);
mImageView.startAnimation(animation);
// XML方式实现
// loadAnimationFromXml(R.anim.view_animation_scale2);
ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)// 指定缩放基点及基点XY Type
Animation animation = new ScaleAnimation(1, 2, 1, 2,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);// 本例中此效果与构造方法二相同
animation.setDuration(3000);
mImageView.startAnimation(animation);
// XML方式实现
// loadAnimationFromXml(R.anim.view_animation_scale2);
Xml方式
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="1"
android:toXScale="2"
android:fromYScale="1"
android:toYScale="2"
android:duration="3000">
</scale>
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="1"
android:toXScale="2"
android:fromYScale="1"
android:toYScale="2"
android:pivotX="50%"
android:pivotY="50%"
android:duration="3000">
</scale>
构造方法一效果(以View左上角为缩放基点XY均放大两倍):
构造方法二&三效果(以View中心为缩放基点XY均放大两倍):
今天的内容就到这里了,简单总结下吧!
1.首先介绍了Android动画的分类,大家了解下就可以了;
2.重点介绍了Android视图动画(补间动画)的特点及使用,要点如下:
(1)补间动画是针对视图进行的操作,并不能改变View属性,只能实现简单的透明、平移、旋转和缩放动画;
(2)补间动画都可以通过代码和Xml两种方式实现相同的效果,两者都比较简单,可以根据需要使用;
(3)在使用代码方式获取Animation实例时,重点理解构造函数传入的参数,特别是XY Type的含义。
下一篇将介绍Android帧动画的特点及使用~~