Android XML动画资源文件详细讲解(上)

前言

此篇主要介绍Android animation xml动画资源Property Animation。。
android动画资源可以分2中类型:一种是以Property为单位动画效果,这种类型的动画主要是对某一个或者多个属性设置动画效果,比如textColor,layout_x等;另一种是以View为单位的动画效果,比如Tween Animation(补间动画)和Frame Animation(逐帧动画)。

一、Property Animation

给控件的某一个属性设置动画效果,比如颜色变化、透明度变化等。

使用也很简单,先来看看标准的语法格式,如下:

1、语法格式

<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>
</set>
解析说明:
上面的语法属性基本是字面意思。在此只说明3个属性:
android:ordering 的取值together和sequentially,分别表示同时执行和按照顺序执行。
android:startOffset 表示延迟多久开始。单位是毫秒。
android:valueType取值intType和floatType。表示当前valueFrom和valueTo的取值类型。如果value取值为颜色值,则不需要指定valueType的类型。

<ObjectAnimator>和<animator>的区别在下面的使用中会提到。

2、使用

说到动画XML资源的使用,必须先介绍几个属性动画相关的Java类:ObjectAnimator、ValueAnimator、AnimatorSet。其中ObjectAnimator是ValueAnimator的子类,AnimatorSet是控制多个动画播放的控制类。接下来的实例中,会使用到这3个类。上面语法格式中提到的<ObjectAnimator>和<animator>,分别对应的Java类为ObjectAnimator和ValueAnimator。

由此可知<animator>只是<ObjectAnimator>一个比较抽象的表示形式,没有制定具体的Property Name,因为ObjectAnimator是ValueAnimator的子类,ValueAnimator或者说<animator>是具有更抽象和灵活的特性。


接下来,我们使用同一个动画效果,介绍<ObjectAnimator>和<animator>的使用和区别。

例子:

1、使用<ObjectAnimator>和ObjectAnimator来实现动画效果。

XML动画资源文件res/animator/property_animation.xml
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" 
    	android:propertyName="x"
	    android:duration="5000"
	    android:startOffset="1000"
	    android:valueFrom="1"
	    android:valueTo="700"
	    android:repeatCount="3"
	    android:repeatMode="reverse"/>
改变属性x值从1到700,重复3次,重复方式为reverse,延迟1秒开始,持续5秒钟。

布局文件res/layout/main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	    android:layout_width="match_parent"
	    android:layout_height="match_parent"
	    android:id="@+id/ab_ll"> 
	    <TextView
	        android:id="@+id/text01"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:textColor="@android:color/white"
	        android:background="@android:color/black" />
     </RelativeLayout>


布局中只有一个TextView控件。 我们要实现的就是将TextView从左边滑动到右边的动画效果。下面看看在activity中的代码实现:
textView1 = (TextView) findViewById(R.id.text01);
		//将XML动画资源实例化为ObjectAnimator对象
		ObjectAnimator animation = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.property_animation);
		animation.setTarget(textView1);
		animation.start();

这就是<ObjectAnimator>的使用方式,很简单。使用的代码只有3行。动画效果提前在xml中配置好。效果如下:



2、使用<animator>和ValueAnimator实现同上的动画效果。
之所以使用同一个例子,主要是介绍<animator>和<objectAnimator>的区别和相同点,以及<animator>的使用。

XML动画资源文件res/animator/property_animation.xml
<animator xmlns:android="http://schemas.android.com/apk/res/android" 
	    android:duration="5000"
	    android:startOffset="1000"
	    android:valueFrom="1"
	    android:valueTo="700"
	    android:repeatCount="3"
	    android:repeatMode="reverse"/>
相比上面的<objectAnimator>,<animator>只是没有propertyName属性,也就是说<animator>没有制定特定的属性类型。

布局文件同上,就不重复粘贴了。关键是activity中的使用代码会跟ObjectAnimator有所不同:
//将XML动画资源实例化为ObjectAnimator对象
		ValueAnimator animation = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.property_animation);
		animation.setTarget(textView1);
		animation.start();
		animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				// TODO Auto-generated method stub
				textView1.setX((Float)animation.getAnimatedValue());
			}
		});
通过上面的代码可以发现,和ObjectAnimator相比,多了animation.addUpdateListener这个方法,此方法是动画生命周期数据变化的一个监听,在这个方法中,我们对需要Target View进行属性值的设置,从而达到想要的动画效果。

相比<ObjectAnimator>,  <animator>的重用性更好,更加灵活。比如我们需要对X和Y轴同时进行动画,我们只需要在上面的代码中加上一行代码就行,如下:
animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				// TODO Auto-generated method stub
				textView1.setX((Float)animation.getAnimatedValue());
				textView1.setY((Float)animation.getAnimatedValue());
			}
		});
这样X轴、Y轴同时都进行移动,效果如下:



那这样看来感觉<objectAnimator>只能实现单个属性的动画,<animator>可以多个属性具有同一个动画生命周期。这也是<animator>复用性更好,更灵活的原因。
如果要使用<objectAnimator>实现同时完成多个属性的动画效果,也是有办法的,具体操作如下:

xml动画资源文件:
<set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:ordering="together">
    <objectAnimator 
    	android:propertyName="x"
	    android:duration="5000"
	    android:startOffset="1000"
	    android:valueFrom="1"
	    android:valueTo="700"
	    android:repeatCount="3"
	    android:repeatMode="reverse"/>
    <objectAnimator 
    	android:propertyName="y"
	    android:duration="5000"
	    android:valueFrom="1"
	    android:valueTo="700"
	    android:repeatCount="3"
	    android:repeatMode="reverse"/>
</set>

没错,就是使用2个<objectAnimator>完成。如上同时写上X和Y的动画属性。然后,在Java代码中使用如下:
//将XML动画资源实例化为ObjectAnimator对象
		AnimatorSet animation =  (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.property_animation);
		animation.setTarget(textView1);
		animation.start();
注意,上面使用的AnimatorSet类,这是一个可以同时播放多个动画效果的类。 这样就可以同时改变X、Y轴的值,实现动画效果。 


动画的监听事件:

animation.addListener(new Animator.AnimatorListener() {
			
			@Override
			public void onAnimationStart(Animator animation) {
				// TODO Auto-generated method stub
				//动画开始
			}
			
			@Override
			public void onAnimationRepeat(Animator animation) {
				// TODO Auto-generated method stub
				//动画重复
			}
			
			@Override
			public void onAnimationEnd(Animator animation) {
				// TODO Auto-generated method stub
				//动画生命周期结束
			}
			
			@Override
			public void onAnimationCancel(Animator animation) {
				// TODO Auto-generated method stub
				//动画取消
			}
		});

通过动画开始和结束的监听事件,我们可以完成一些效果,比如动画结束后调转、或者隐藏等。

3、扩展使用

上面我们介绍了Animation的基本语法和简单使用。接下来,我们稍微进阶一下用法。
比如:
当TextView移动的过程中,当X移动到0、40、80距离是,字体颜色分别发生3种不同的变化。如下图效果:



实现代码:(此处完全使用Java代码完成)
ValueAnimator animation =  new ValueAnimator();
		animation.setDuration(5000);
		animation.setObjectValues(new MineAnimatorType());
		animation.setRepeatMode(Animation.REVERSE);
		animation.setRepeatCount(4);
		animation.setInterpolator(new LinearInterpolator());  
		animation.setEvaluator(new TypeEvaluator<MineAnimatorType>() {

			@Override
			public MineAnimatorType evaluate(float fraction,
					MineAnimatorType startValue, MineAnimatorType endValue) {
				// TODO Auto-generated method stub
				MineAnimatorType mineAnimatorType = new MineAnimatorType();
				Log.d("ddd", "-->"+fraction*200);
				mineAnimatorType.x = fraction*200;
				mineAnimatorType.y = fraction*1.5F*200;
				if (mineAnimatorType.x > 80) {
					mineAnimatorType.color = Color.RED;
				} else if (mineAnimatorType.x < 40) {
					mineAnimatorType.color = Color.BLUE;
				} else {
					mineAnimatorType.color = Color.GREEN;
				}
				return mineAnimatorType;
			}
			
		});
		animation.start();
		animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				// TODO Auto-generated method stub
				MineAnimatorType mineAnimatorType=(MineAnimatorType) animation.getAnimatedValue();
				textView1.setX(mineAnimatorType.x);
				textView1.setY(mineAnimatorType.y);
				textView1.setTextColor(mineAnimatorType.color);
			}
		});
1、以上setInterpolator()方法是改变动画播放速度,取值如下:
AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速
AccelerateInterpolator  在动画开始的地方速率改变比较慢,然后开始加速
AnticipateInterpolator 开始的时候向后然后向前甩
AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
BounceInterpolator   动画结束的时候弹起
CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
DecelerateInterpolator 在动画开始的地方快然后慢
LinearInterpolator   以常量速率改变
OvershootInterpolator    向前甩一定值后再回到原来位置

其中MineAnimatorType是自定义的一个类,代码如下:
class MineAnimatorType{
		public float x;
		public float y;
		public int color;
		public float getX() {
			return x;
		}
		public void setX(float x) {
			this.x = x;
		}
		public float getY() {
			return y;
		}
		public void setY(float y) {
			this.y = y;
		}
		public int getColor() {
			return color;
		}
		public void setColor(int color) {
			this.color = color;
		}
		
	}
以上是动画扩展使用的基本方式。其中setObjectValues定义指定的数据类型,setInterpolator设定动画速率,setEvaluator此方法为自定义值的变化方式。


实例2:画圆的动画,对上面的例子进行修改之后,可以实现画圆动画。
画园和画直线唯一的区别就是X、Y的值变化的方式不一样,所以我们只需要改变setEvaluator方法中X\Y的计算方式就行了,代码如下:
animation.setEvaluator(new TypeEvaluator<MineAnimatorType>() {

			@Override
			public MineAnimatorType evaluate(float fraction,
					MineAnimatorType startValue, MineAnimatorType endValue) {
				// TODO Auto-generated method stub
				MineAnimatorType mineAnimatorType = new MineAnimatorType();
				Log.d("ddd", "-->"+fraction);
				mineAnimatorType.x = (float) Math.cos(fraction*Math.PI*2)*100+300;
				mineAnimatorType.y = (float) (Math.sin(fraction*Math.PI*2)*100)+300;
				
				return mineAnimatorType;
			}
			
		});
效果如下:




以上主要是介绍XML动画资源之Property Animation的使用,和一些简单的示例。
通过这些基本的用法,加上合理的算法,我们可以完成很炫的效果。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨景文Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值