Android动画之属性动画

Android中的动画分为三种:View动画帧动画属性动画

属性动画

一、简介

属性动画是API 11 新加入的动画特性,对于API 11之前的版本可以使用开源的动画库nineoldandroids来兼容之前的版本。Google引入属性动画是为了解决view动画的一些缺陷。

view动画的缺陷:

1、只能够作用在视图View上,即只可以对一个Button、TextView、LinearLayout或者其它继承自View的组件进行动画操作,但无法对非View的对象进行动画操作。
	 
2、只是改变了View的视觉效果,而不会真正去改变View的属性。
	
3、效果单一,只能实现平移、旋转、缩放 & 透明度这些简单的动画需求。

属性动画的作用对象是任意的Java对象。可实现各种动画效果。

属性动画的工作原理:在一定的时间内,通过不断的对值进行改变,并将该值赋值给对象的属性,从而实现动画效果。

实现属性动画涉及到三个类ObjectAnimator、ValueAnimator、AnimatorSet

二、ObjectAnimator

直接对对象的属性值进行改变操作,从而实现动画效果。底层的动画实现机制是基于ValueAnimator类。

具体使用,Java代码和xml:

1、Java代码

//创建动画实例
ObjectAnimator animator = ObjectAnimator.ofFloat(Object object, String property, float ....values);  
// 设置动画运行的时长
anim.setDuration(500);
// 设置动画延迟播放时间
anim.setStartDelay(500);
// 设置动画重复播放次数
anim.setRepeatCount(0);
//设置重复播放动画模式RESTART(默认)正序重放/REVERSE:倒序回放
anim.setRepeatMode(ValueAnimator.RESTART);
// 启动动画
animator.start(); 

2、在XML 代码中设置

<1> 首先在res目录下创建animator文件夹
			
<2> 在res/animator 的文件夹里创建动画效果test_animator.xml文件
            
       <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"  
               android:valueFrom="1"   // 初始值
               android:valueTo="0"  // 结束值
               android:valueType="floatType"  // 变化值类型 :floatType & intType
               android:propertyName="alpha" // 对象变化的属性名称/>  
			
<3> 启动动画
	// 载入XML动画
	Animator animator = AnimatorInflater.loadAnimator(context, R.animator.view_animation);  
    // 设置动画对象
    animator.setTarget(view);  
    // 启动动画
    animator.start();

3、基本属性:

Alpha          控制View的透明度               float 
		
TranslationX   控制X方向的位移                float 
		
TranslationY   控制Y方向的位移                float 
		
ScaleX         控制X方向的缩放倍数            float 
		
ScaleY         控制Y方向的缩放倍数            float
		
Rotation       控制以屏幕方向为轴的旋转度数   float
		
RotationX      控制以X轴为轴的旋转度数        float
		
RotationY      控制以Y轴为轴的旋转度数        float 

4、任意属性:

属性动画要求作用的对象提供该属性的get和set方法,如果想让动画生效,需要满足:

1、该对象属性必须提供set方法,属性动画需要使用set方法来设置属性值	

2、如果没有设置动画的初始值的话,还需要提供get方法来获取初始值

3、 getff(如果需要)和set方法必须是相同的类型

如果该属性没有set、get方法的话或者是set方法中没有对属性进行相应的操作,比如Button中的setWidth()方法,该方法 是TextView中的方法,是为了设置TextView的最大最小宽度的,而没有设置Button的宽度,所以通过setWidth无法改变Button的宽度,此时对width做属性动画就没有效果。

对于这个问题,官方给了三种解决方法:

1、给对象添加get、set方法,如果有权限的话(很多时候没权限去这么做,当然在自定义view中可以使用此方法)	

2、使用一个类来包装原始对象。间接为对象的属性提供get和set方法

3、利用ValueAnimator	

下面简单介绍一下第二种方法的使用:

<1> 创建一个类,比如ViewWrapper
			
	public class ViewWrapper{
					
		priavte View mTarget;
						
		public ViewWrapper(View target){		
			mTarget = target;  	 
		}
						
		public int getWidth(){
			return mTarget.getLayoutParams.width;
		}
						
		public void setWidth(int width){
			mTarget.getLayoutParams.width = width;
			mTarget.requestLayout();
		}
				
}

<2> 实例化ViewWrapper类,开始动画
			
	ViewWrapper wrapper = new ViewWrapper(button);
	//让Button的宽度在5秒内变化到500
	ObjectAnimator.ofInt(wrapper,"width",500).setDuration(5000).start();

三、VauleAnimator

ValueAnimator是整个属性动画机制当中最核心的一个类,属性动画的运行机制是通过不断地对值进行操作来实现的,而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的。它的内部使用一种时间循环的机制来计算值与值之间的动画过渡,只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长,那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。 除此之外,ValueAnimator还负责管理动画的播放次数、播放模式、以及对动画设置监听器等。

使用:
获取ValueAnimator实例可以通过ofInt(), ofFloat(), or ofObject()来获取。比如:
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
//将改变的值手动赋值给对象的属性值:通过动画的更新监听器
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
     @Override
     public void onAnimationUpdate(ValueAnimator animation) {
          // 获得改变后的值
          int currentValue = (Integer) animation.getAnimatedValue();    
          //将改变后的值赋给对象的属性值,下面会详细说明
		  ...
          //刷新视图,即重新绘制,从而实现动画效果
		  ... 
      }
});
animation.start();

ValueAnimator.ofObject()

将初始值 以对象的形式 过渡到结束值 即通过操作 对象 实现动画效果。在使用ValueAnimator.ofObject()的时候需要使用到估值器(TypeEvaluator)。

myObject object1 = new myObject();  
myObject object2 = new myObject();  
ValueAnimator anim = ValueAnimator.ofObject(new myObjectEvaluator(), object1, object2);

Interpolator 插值器

是一个接口,作用是设置属性值从初始值过渡到结束值的变化速率,比如匀速、加速 & 减速 等等。 实现非线性运动的动画效果。

Android系统内部内置了9种插值器:

加速@android:anim/accelerate_interpolatorAccelerateInterpolator
完成超出再回到结束位置@android:anim/overshoot_interpolatorOvershootInterpolator
先加速再减速@android:anim/accelerate_decelerate_interpolatorAccelerateDecelerateInterpolator
先退后再加速前进@android:anim/anticipate_interpolatorAnticipateInterpolator
先退后再加速前进,超出终点后再回终点@android:anim/anticipate_overshoot_interpolatorAnticipateOvershootInterpolator
最后阶段弹球效果@android:anim/bounce_interpolatorBounceInterpolator
周期运动@android:anim/cycle_interpolatorCycleInterpolator
减速@android:anim/decelerate_interpolatorDecelerateInterpolator
匀速@android:anim/linear_interpolatorLinearInterpolator

自定义插值器

自定义插值器需要实现 Interpolator接口 & 复写getInterpolation()方法。

public class CustomInterpolator implements Interpolator {
            @Override
            public float getInterpolation(float input) {
                return (float) Math.sin((input) * Math.PI * 0.5F);
            }
}	

TypeEvaluator 估值器

接口。作用是设置属性值从初始值过渡到结束值的变化具体数值。
插值器(Interpolator)决定 值 的变化规律(匀速、加速blabla),即决定的是变化趋势;而接下来的具体变化数值则交给而估值器。

系统内置了3中估值器:

IntEvaluator:  针对整型属性 
FloatEvaluator:针对浮点型属性 
ArgbEvaluator: 针对Color属性     

自定义估值器

自定义估值器需要实现 TypeEvaluator接口 & 复写evaluate()函数

// 实现TypeEvaluator接口
public class ObjectEvaluator implements TypeEvaluator{  
        // 复写evaluate()
        // 在evaluate()里写入对象动画过渡的逻辑
        @Override  
        public Object evaluate(float fraction, Object startValue, Object endValue) {  
            // 参数说明
            // fraction:表示动画完成度(根据它来计算当前动画的值)
            // startValue、endValue:动画的初始值和结束值
            ... 
            return value;  
            // 返回对象动画过渡的逻辑计算后的值
}  

TimeInterpolator和TypeEvaluator是怎么协同工作的呢?

它们是实现非匀速动画的重要手段。属性动画是对属性做动画,属性要实现动画:
首先由TimeInterpolator(插值器)根据时间流逝的百分比计算出当前属性值改变的百分比,并将这个百分比返回,这个时候插值器的工作就完成了。比如插值器返回的值是0.5,很显然要的不是0.5,而是当前属性的值,即当前属性变成了什么值,这就需要估值器根据当前属性改变的百分比来计算改变后的属性值,根据这个属性值,就可以设置当前属性的值了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值