欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android动画之属性动画

程序员文章站 2022-05-03 10:36:45
...

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_interpolator AccelerateInterpolator
完成超出再回到结束位置 @android:anim/overshoot_interpolator OvershootInterpolator
先加速再减速 @android:anim/accelerate_decelerate_interpolator AccelerateDecelerateInterpolator
先退后再加速前进 @android:anim/anticipate_interpolator AnticipateInterpolator
先退后再加速前进,超出终点后再回终点 @android:anim/anticipate_overshoot_interpolator AnticipateOvershootInterpolator
最后阶段弹球效果 @android:anim/bounce_interpolator BounceInterpolator
周期运动 @android:anim/cycle_interpolator CycleInterpolator
减速 @android:anim/decelerate_interpolator DecelerateInterpolator
匀速 @android:anim/linear_interpolator LinearInterpolator

自定义插值器

自定义插值器需要实现 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,而是当前属性的值,即当前属性变成了什么值,这就需要估值器根据当前属性改变的百分比来计算改变后的属性值,根据这个属性值,就可以设置当前属性的值了。

相关标签: Android