View Animation: 视图动画在古老的Android版本系统中就已经提供了,只能被用来设置View的动画。
Drawable Animation: 这种动画(也叫Frame动画、帧动画)其实可以划分到视图动画的类别,专门用来一个一个的显示Drawable的resources,就像放幻灯片一样。
Property Animation: 属性动画只对Android 3.0(API 11)以上版本的Android系统才有效,这种动画可以设置给任何Object,包括那些还没有渲染到屏幕上的对象。这种动画是可扩展的,可以让你自定义任何类型和属性的动画。
View Animation(视图动画)使用详解
2-1 视图动画概述
视图动画,也叫Tween(补间)动画可以在一个视图容器内执行一系列简单变换(位置、大小、旋转、透明度)。譬如,如果你有一个TextView对象,您可以移动、旋转、缩放、透明度设置其文本,当然,如果它有一个背景图像,背景图像会随着文本变化。
补间动画通过XML或Android代码定义,建议使用XML文件定义,因为它更具可读性、可重用性。
如下是视图动画相关的类继承关系:
Animation属性详解
Android的animation由四种类型组成:
Animation主要有两种动画模式:
步骤如下:
①新建 Android 项目
②在res目录中新建anim文件夹
③在anim目录中新建一个my_anim.xml(注意文件名小写)
④在 my_anim.xml 加入动画代码
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<alpha />
<scale />
<translate />
<rotate />
set>
4.1 alpha 渐变透明度动画效果
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<alpha
android:duration="1000"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
set>
4.2 scale 渐变尺寸伸缩动画效果
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<scale
android:duration="1000"
android:fillAfter="false"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.4"
android:toYScale="1.4" />
set>
4.3 translate 画面转换位置移动动画效果
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="2000"
android:fromXDelta="30"
android:fromYDelta="30"
android:toXDelta="-80"
android:toYDelta="300" />
set>
4.4 rotate 画面转移旋转动画效果
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<rotate
android:duration="3000"
android:fromDegrees="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="+350" />
set>
视图动画注意事项
关于视图动画(补间动画)的例子我就不介绍了,网上简直多的都泛滥了。只是强调在使用补间动画时注意如下一点即可: 特别特别注意:补间动画执行之后并未改变View的真实布局属性值。切记这一点,譬如我们在Activity中有一个 Button在屏幕上方,我们设置了平移动画移动到屏幕下方然后保持动画最后执行状态呆在屏幕下方,这时如果点击屏幕下方动画执行之后的Button是没 有任何反应的,而点击原来屏幕上方没有Button的地方却响应的是点击Button的事件。
插值器使用方法
插值器的使用比较简答,如下
"@android:anim/accelerate_interpolator">
...
插值器的自定义
有时候你会发现系统提供的插值器不够用,可能就像View一样需要自定义。所以接下来我们来看看插值器的自定义,关于插值器的自定义分为两种实现方式,xml自定义实现(其实就是对现有的插值器的一些属性修改)或者java代码实现方式。如下我们来说说。
先看看XML自定义插值器的步骤:
在res/anim/目录下创建filename.xml文件。
修改你准备自定义的插值器如下:
rawable动画其实就是Frame动画(帧动画),它允许你实现像播放幻灯片一样的效果,这种动画的实质其实是Drawable,所以这种动画的XML定义方式文件一般放在res/drawable/目录下。
Drawable动画详细说明
我们依旧可以使用xml或者java方式实现帧动画。但是依旧推荐使用xml,具体如下:
必须是根节点,包含一个或者多个元素,属性有:
android:oneshot true代表只执行一次,false循环执行。
类似一帧的动画资源。
animation-list的子项,包含属性如下:
android:drawable 一个frame的Drawable资源。
android:duration 一个frame显示多长时间。
在使用属性动画之前先来看几个常用的View属性成员:
translationX,translationY:控制View的位置,值是相对于View容器左上角坐标的偏移。
rotationX,rotationY:控制相对于轴心旋转。
x,y:控制View在容器中的位置,即左上角坐标加上translationX和translationY的值。
alpha:控制View对象的alpha透明度值。
属性动画概述
Android 3.0以后引入了属性动画,属性动画可以轻而易举的实现许多View动画做不到的事,上面也看见了,View动画无非也就做那几种事情,别的也搞不定,而 属性动画就可以的,譬如3D旋转一张图片。其实说白了,你记住一点就行,属性动画实现原理就是修改控件的属性值实现的动画。
XML方式属性动画
在xml中可直接用的属性动画节点有ValueAnimator、ObjectAnimator、AnimatorSet
"together" | "sequentially"]>
"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"]/>
"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"]/>
...
XML属性动画使用方法:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
R.animtor.property_animator);
set.setTarget(myObject);
set.start();
Java方式属性动画
1、ObjectAnimator:继承自ValueAnimator,允许你指定要进行动画的对象以及该对象 的一个属性。该类会根据计算得到的新值自动更新属性。大多数的情况使用ObjectAnimator就足够了,因为它使得目标对象动画值的处理过程变得足 够简单,不用像ValueAnimator那样自己写动画更新的逻辑,但是ObjectAnimator有一定的限制,比如它需要目标对象的属性提供指定 的处理方法(譬如提供getXXX,setXXX方法),这时候你就需要根据自己的需求在ObjectAnimator和ValueAnimator中看 哪种实现更方便了。
ObjectAnimator类提供了ofInt、ofFloat、ofObject这个三个常用的方法,这些方法都是设置动画作用的元素、属性、开始、结束等任意属性值。当属性值(上面方法的参数)只设置一个时就把通过getXXX反射获取的值作为起点,设置的值作为终点;如果设置两个(参数),那么一个是开始、另一个是结束。
特别注意:ObjectAnimator的动画原理是不停的调用setXXX方法更新属性值,所有使用ObjectAnimator更新属性时的前提是Object必须声明有getXXX和setXXX方法。
我们通常使用ObjectAnimator设置View已知的属性来生成动画,而一般View已知属性变化时都会主动触发重绘图操作,所以动画会自 动实现;但是也有特殊情况,譬如作用Object不是View,或者作用的属性没有触发重绘,或者我们在重绘时需要做自己的操作,那都可以通过如下方法手 动设置:
ObjectAnimator mObjectAnimator= ObjectAnimator.ofInt(view, "customerDefineAnyThingName", 0, 1).setDuration(2000);
mObjectAnimator.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
//int value = animation.getAnimatedValue(); 可以获取当前属性值
//view.postInvalidate(); 可以主动刷新
//view.setXXX(value);
//view.setXXX(value);
//......可以批量修改属性
}
});
如下是一个我在项目中的Y轴3D旋转动画实现实例:
ObjectAnimator.ofFloat(view, "rotationY", 0.0f, 360.0f).setDuration(1000).start();
PropertyValuesHolder:多属性动画同时工作管理类。有时候我们需要同时修改多个属性,那就可以用到此类,具体如下:
PropertyValuesHolder a1 = PropertyValuesHolder.ofFloat("alpha", 0f, 1f);
PropertyValuesHolder a2 = PropertyValuesHolder.ofFloat("translationY", 0, viewWidth);
......
ObjectAnimator.ofPropertyValuesHolder(view, a1, a2, ......).setDuration(1000).start();
如上代码就可以实现同时修改多个属性的动画啦。
3、ValueAnimator:属性动画中的时间驱动,管理着动画时间的开始、结束属性值,相应时间属性值计算方法等。包含所有计算动画值的核心函数以及每一个动画时间节点上的信息、一个动画是否重复、是否监听更新事件等,并且还可以设置自定义的计算类型。
特别注意:ValueAnimator只是动画计算管理驱动,设置了作用目标,但没有设置属性,需要通过updateListener里设置属性才会生效。
ValueAnimator animator = ValueAnimator.ofFloat(0, mContentHeight); //定义动画
animator.setTarget(view); //设置作用目标
animator.setDuration(5000).start();
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation){
float value = (float) animation.getAnimatedValue();
view.setXXX(value); //必须通过这里设置属性值才有效
view.mXXX = value; //不需要setXXX属性方法
}
});
public static Animation loadAnimation (Context context, int id)
//第一个参数Context为程序的上下文
//第二个参数id为动画XML文件的引用
//例子:
myAnimation= AnimationUtils.loadAnimation(this,R.anim.my_anim);
//使用AnimationUtils类的静态方法loadAnimation()来加载XML中的动画XML文件
//在代码中定义 动画实例对象
private Animation myAnimation_Alpha;
private Animation myAnimation_Scale;
private Animation myAnimation_Translate;
private Animation myAnimation_Rotate;
//根据各自的构造方法来初始化一个实例对象
myAnimation_Alpha=new AlphaAnimation(0.1f, 1.0f);
myAnimation_Scale =new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
myAnimation_Translate=new TranslateAnimation(30.0f, -80.0f, 30.0f, 300.0f);
myAnimation_Rotate=new RotateAnimation(0.0f, +350.0f,
Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f);
7.1 AlphaAnimation
① AlphaAnimation类对象定义
private AlphaAnimation myAnimation_Alpha
② AlphaAnimation类对象构造
//第一个参数fromAlpha为 动画开始时候透明度
//第二个参数toAlpha为 动画结束时候透明度
AlphaAnimation(float fromAlpha, float toAlpha)
//说明:0.0表示完全透明,1.0表示完全不透明
myAnimation_Alpha=new AlphaAnimation(0.1f, 1.0f);
③ 设置动画持续时间
//设置时间持续时间为 5000毫秒
myAnimation_Alpha.setDuration(5000);
7.2 ScaleAnimation
① ScaleAnimation类对象定义
② ScaleAnimation类对象构造
ScaleAnimation(float fromX, float toX, float fromY, float toY,
int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
//第一个参数fromX为动画起始时 X坐标上的伸缩尺寸
//第二个参数toX为动画结束时 X坐标上的伸缩尺寸
//第三个参数fromY为动画起始时Y坐标上的伸缩尺寸
//第四个参数toY为动画结束时Y坐标上的伸缩尺寸
/*说明:
以上四种属性值
0.0表示收缩到没有
1.0表示正常无伸缩
值小于1.0表示收缩
值大于1.0表示放大
*/
//第五个参数pivotXType为动画在X轴相对于物件位置类型
//第六个参数pivotXValue为动画相对于物件的X坐标的开始位置
//第七个参数pivotXType为动画在Y轴相对于物件位置类型
//第八个参数pivotYValue为动画相对于物件的Y坐标的开始位置
myAnimation_Scale =new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
③ 设置动画持续时间
//设置时间持续时间为 700毫秒
myAnimation_Scale.setDuration(700);
7.3 TranslateAnimation
① TranslateAnimation类对象定义
② TranslateAnimation类对象构造
//第一个参数fromXDelta为动画起始时 X坐标上的移动位置
//第二个参数toXDelta为动画结束时 X坐标上的移动位置
//第三个参数fromYDelta为动画起始时Y坐标上的移动位置
//第四个参数toYDelta为动画结束时Y坐标上的移动位置
TranslateAnimation(float fromXDelta, float toXDelta,float fromYDelta, float toYDelta)
③ 设置动画持续时间
//设置时间持续时间为 2000毫秒
myAnimation_Translate.setDuration(2000);
7.4 RotateAnimation
② RotateAnimation类对象构造
RotateAnimation(float fromDegrees, float toDegrees,int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
//第一个参数fromDegrees为动画起始时的旋转角度
//第二个参数toDegrees为动画旋转到的角度
//第三个参数pivotXType为动画在X轴相对于物件位置类型
//第四个参数pivotXValue为动画相对于物件的X坐标的开始位置
//第五个参数pivotXType为动画在Y轴相对于物件位置类型
//第六个参数pivotYValue为动画相对于物件的Y坐标的开始位置
myAnimation_Rotate=new RotateAnimation(0.0f, +350.0f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f);
8.如何使用Java代码中的动画效果
使用从View父类继承过来的方法startAnimation()来为View或是子类View等等添加一个动画效果
public void startAnimation (Animation animation)
public class AnimationActivity extends Activity implements OnClickListener {
private ImageView imgPic;
private Button btnAlpha, btnScale, btnTranslate, btnRotate;
private Animation myAnimation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation);
intiView();
initData();
}
/**
* 初始化组件
*/
private void intiView() {
imgPic = (ImageView) findViewById(R.id.imgPic);
btnAlpha = (Button) findViewById(R.id.btnAlpha);
btnScale = (Button) findViewById(R.id.btnScale);
btnTranslate = (Button) findViewById(R.id.btnTranslate);
btnRotate = (Button) findViewById(R.id.btnRotate);
}
/**
* 初始化数据
*/
private void initData() {
btnAlpha.setOnClickListener(this);
btnScale.setOnClickListener(this);
btnTranslate.setOnClickListener(this);
btnRotate.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnAlpha:
/**
* 使用XML中的动画效果 第一个参数Context为程序的上下文 第二个参数id为动画XML文件的引用
*/
myAnimation = AnimationUtils.loadAnimation(this, R.anim.alpha_anim);
imgPic.startAnimation(myAnimation);
break;
case R.id.btnScale:
myAnimation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
imgPic.startAnimation(myAnimation);
break;
case R.id.btnTranslate:
myAnimation = AnimationUtils.loadAnimation(this,
R.anim.translate_anim);
imgPic.startAnimation(myAnimation);
break;
case R.id.btnRotate:
myAnimation = AnimationUtils
.loadAnimation(this, R.anim.rotate_anim);
imgPic.startAnimation(myAnimation);
break;
}
}
}
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false" >
<item
android:drawable="@drawable/cmmusic_progress_1"
android:duration="150">
item>
<item
android:drawable="@drawable/cmmusic_progress_2"
android:duration="150">
item>
<item
android:drawable="@drawable/cmmusic_progress_3"
android:duration="150">
item>
<item
android:drawable="@drawable/cmmusic_progress_4"
android:duration="150">
item>
<item
android:drawable="@drawable/cmmusic_progress_5"
android:duration="150">
item>
<item
android:drawable="@drawable/cmmusic_progress_6"
android:duration="150">
item>
<item
android:drawable="@drawable/cmmusic_progress_7"
android:duration="150">
item>
<item
android:drawable="@drawable/cmmusic_progress_8"
android:duration="150">
item>
animation-list>
③主界面页面布局设置,太简单,不赘述了
④主界面代码如下:
public class AnimationActivity extends Activity implements OnClickListener {
private ImageView imgPic;
private Button btnStart, btnStop;
private AnimationDrawable animationDrawable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation);
intiView();
initData();
}
/**
* 初始化组件
*/
private void intiView() {
imgPic = (ImageView) findViewById(R.id.imgPic);
btnStart = (Button) findViewById(R.id.btnStart);
btnStop = (Button) findViewById(R.id.btnStop);
}
/**
* 初始化数据
*/
private void initData() {
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
//Sets a drawable as the content of this ImageView.
imgPic.setImageResource(R.drawable.loading_anim);
//给动画资源赋值
animationDrawable = (AnimationDrawable) imgPic.getDrawable();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStart:
animationDrawable.start();//开始
break;
case R.id.btnStop:
animationDrawable.stop(); //停止
break;
}
}
}