android Animation介绍

1、创建Animation对象

Animation animation = new Animation(){
 @Override
 protected void applyTransformation(float interpolatedTime, Transformation t) {
 super.applyTransformation(interpolatedTime, t);        Log.d("zgx","interpolatedTime=========="+interpolatedTime);
Log.d("zgx","getAlpha==============="+t.getAlpha());
Log.d("zgx","getTransformationType======="+t.getTransformationType());          Log.d("zgx","getMatrix==============="+t.getMatrix());
     }
}

从上面代码我们可以看到,每个动画都重载了父类的applyTransformation方法。这个方法的主要作用就是把一些属性组装成一个Transformation类。这个方法会被父类的getTransformation方法调用。
再来看看一些类的使用。

2. initialize方法

public void initialize(int width, int height, int parentWidth, int parentHeight)
初始化工作,动画开始前的一些准备工作。

3. Interpolator方法

public void setInterpolator(Interpolator i)

定义动画执行过程一些加速度减速度,为了我们后面Transformation来服务的。

4. Transformation类

Transformation记录了仿射矩阵Matrix,动画每触发一次,会对原来的矩阵做一次运算,View的Bitmap与这个矩阵相乘就可以实现相应的操作(旋转、平移、缩放等)。

Transformation类封装了矩阵和alpha值,它有两个重要的成员,一是mMatrix,二是mAlpha(控制透明度)。

5.View中实现动画的过程
图形变换通过矩阵实现。图形变换是图形学中基本知识。简单来说就是,每种变换都是一次矩阵运算。在Android中,Canvas类包含当前矩阵,当前调用Canvas.drawBitmap(bm,x,y,Paint)绘制时,android会先把bmp做一次矩阵运算,然后将运算结果显示在Canvas上。这样编程人员只需不断修改Canvas的矩阵并刷新屏幕,View里对象就会不停的做图形变换,动画就形成了。
View创建动画对象,设置动画属性,调用invalidate刷新屏幕,启动动画;
invalidate方法触发了onDraw函数;在onDraw函数中,调用动画的getTransformation方法,得到当前时间点的矩阵将该矩阵设置成Canvas的当前矩阵调用canvas的drawBitmap方法,绘制屏幕。判断getTransformation的返回值,若为真,调用invalidate方法,刷新屏幕进入下一帧;若为假,说明动画完成。

6、setRepeatCount(int repeatCount)
//设置重复次数,INFINITE为无限 。

animation .setRepeatMode(Animation.RESTART);  

7、setRepeatMode(int repeatMode)
设置重复模式,RESTART为结束后重新开始,REVERSE为按原来的轨迹逆向返回

animation.setRepeatMode(Animation.RESTART);
animation.setRepeatMode(Animation.REVERSE);

8、setAnimationListener(Animation.AnimationListener listener)

     animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            //动画开始处理
            }

            @Override
            public void onAnimationEnd(Animation animation) {
            //动画结束处理

            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                //动画重新开始的时候处理
            }
        });

9、setInterpolator(Interpolator i)

switch (position) {  
            case 0:  
                //加速进入  
                animation.setInterpolator(AnimationUtils.loadInterpolator(this,  
                        android.R.anim.accelerate_interpolator));  
                break;  
            case 1:  
                //减速进入  
                animation.setInterpolator(AnimationUtils.loadInterpolator(this,  
                        android.R.anim.decelerate_interpolator));  
                break;  
            case 2:  
                //加速进入.与第一个的区别为当repeatMode为reverse时,仍为加速返回原点  
                animation.setInterpolator(AnimationUtils.loadInterpolator(this,  
                        android.R.anim.accelerate_decelerate_interpolator));  
                break;  
            case 3:  
                //先往后退一点再加速前进  
                animation.setInterpolator(AnimationUtils.loadInterpolator(this,  
                        android.R.anim.anticipate_interpolator));  
                break;  
            case 4:  
                //减速前进,冲过终点前再后退  
                animation.setInterpolator(AnimationUtils.loadInterpolator(this,  
                        android.R.anim.overshoot_interpolator));  
                break;  
            case 5:  
                //case 3,4的结合体  
                animation.setInterpolator(AnimationUtils.loadInterpolator(this,  
                        android.R.anim.anticipate_overshoot_interpolator));  
                break;  
            case 6:  
                //停止前来回振几下  
                animation.setInterpolator(AnimationUtils.loadInterpolator(this,  
                        android.R.anim.bounce_interpolator));  
                break;  
        }  

看完这些方法,我们再来看看Animation的子类吧!
Android包含三种动画: Drawable Animation、View Animation、Property Animation(Android3.0新引入,Android官网推荐使用Property Animation)。

Drawable Animation:
Drawable Animation是逐帧动画,在代码中定义动画帧,使用AnimationDrawable类;XML文件能更简单的组成动画帧,在res/drawable文件夹,使用采用来定义不同的帧。

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
    android:oneshot="true">  
    <item android:drawable="@drawable/frame_1" android:duration="200" />  
    <item android:drawable="@drawable/frame_2" android:duration="200" />  
    <item android:drawable="@drawable/frame_3" android:duration="200" />  
    <item android:drawable="@drawable/frame_4" android:duration="200" />  
</animation-list>

其中android:oneshot=“true”表示该动画只播放一次,等于false时则循环播放。标签定义各个帧显示的图片。显示顺序依照定义顺序。
我们还有一种定义方法就是使用layer-list标签。

<?xml version="1.0" encoding="UTF-8"?>  
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
    android:oneshot="false">  
    <item android:duration="100">  
        <layer-list>  
            <item android:drawable="@drawable/login_loading_00" />  
            <item android:drawable="@drawable/login_loading_10" />  
        </layer-list>  
    </item>  
    <item android:duration="100">  
        <layer-list>  
            <item android:drawable="@drawable/login_loading_01" />  
            <item android:drawable="@drawable/login_loading_11" />  
        </layer-list>  
    </item>  
    </animation-list>  

以上xml文件与前面一个xml文件不大同,多了一个标签,该标签用法很简单,内包含的图片将层叠起来,在同一帧中一起显示。然后调用view的setBackgroundResource(动画资源)这样就行了。得到动画资源通过(AnimationDrawable) loadingImg.getBackground();

View Animation :(Tweened Animation)
View Animation分为4大类:AlphaAnimation,RotateAnimation,ScaleAnimation,
TranslateAnimation,分别对应透明度,旋转,大小,位移四种变化。
基于View的渐变动画,她只改变了View的绘制效果,而实际属性值未变。比如动画移动一个按钮位置,但按钮点击的实际位置仍未改变。View Animation的效果由四个因素决定:1)初始状态;2)结束状态;3)持续时间;4)Interpolator。

例如:

TranslateAnimation tAnim = new TranslateAnimation(0, 400, 0, 0);
 tAnim.setDuration(2000);  
 view.startAnimation(tAnim);  //横向位移400个单位  

但是他并未改变view的属性,下面我们就来改变它的属性:

 tAnim.setAnimationListener(new AnimationListener() {  

    @Override  
    public void onAnimationStart(Animation animation) {  
      // TODO Auto-generated method stub  
       }  
       @Override  
    public void onAnimationRepeat(Animation animation) {  
      // TODO Auto-generated method stub  
       }  
      @Override  
    public void onAnimationEnd(Animation animation) {  
      // TODO Auto-generated method stub  
      LayoutParams params = view.getLayoutParams;
      params.leftMargin = 400;
      view.setLayoutParams(params);
      view.clearAnimation();  
                   }  
              });  
       break;  
      }  
return true;  
}  
});

这样我们就使view真正的往右移动了400单位

Property Animation:
上面view Animation我们发现它并不能真正改变view的属性,下面我们就来看看能改变它属性的Property Animation属性。动画的对象除了传统的View对象,还可以是Object对象,动画之后,Object对象的属性值被实实在在的改变了。Property animation能够通过改变View对象的实际属性来实现View动画。任何时候View属性的改变,View能自动调用invalidate()来刷新。

我们先来看看通过ObjectAnimator实现一张icon由透明到不透明

//11以下的SDK ,导入nineoldandroids动画库
ObjectAnimator.ofFloat(v, "alpha", 0.0f,1.0f)
        .setDuration(100)
        .start();

就是这样,是不是很简单,对于ObjectAnimator 提供了ofInt、ofFloat、ofObject,ofPropertyValuesHolder,这几个方法都是设置动画作用的元素、作用的属性、动画开始、结束、以及中间的任意个属性值。
1、例如:

ObjectAnimator.ofFloat(target, propertyName, values)

target :指的就是我们需要改变属性的view,
propertyName:我们可以任意命名,它的作用是getPropName通过propertyName反射获取后面设置的values值,
values:这个值我们可以设置一个values,也可以设置多个,只设置一个的时候,会认为当然对象该属性的值为开始(getPropName反射获取),然后设置的值为终点。如果设置两个,则一个为开始、一个为结束动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新某个属性,必须得有getter(设置一个属性值的时候)和setter方法。

2、如果我们调用view对象的属性方法没有调用view的重绘,我们就需要自己调用通过:

anim.addUpdateListener(new AnimatorUpdateListener()  
        {  
            @Override  
            public void onAnimationUpdate(ValueAnimator animation)  
            {  
//              view.postInvalidate();  
//              view.invalidate();  
            }  
        });  

来调用。
比如当我们既要透明由不透明到透明。然后慢慢的变小,我们就可以这样实现。

ObjectAnimator anim = ObjectAnimator.ofFloat(v, "alpha", 1.0f,0.0f)
.setDuration(1000);
anim.start();
anim.addUpdateListener(new AnimatorUpdateListener()  
    {  
    @Override  
    public void onAnimationUpdate(ValueAnimator animation)  
    {  
    float cVal = (Float) animation.getAnimatedValue();  
    Log.d("zgx", "cVal==========="+cVal);
     v.setAlpha(cVal);  
     v.setScaleX(cVal);  
     v.setScaleY(cVal);  
        }  
    });  

3、我们再来看看ofPropertyValuesHolder的使用:

public void propertyValuesHolder(View view)  
{  
  PropertyValuesHolder pvhX =    PropertyValuesHolder.ofFloat("alpha", 1f,  
                0f, 1f);  
 PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f,  
                0, 1f);  
PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f,  
                0, 1f);  
ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY,pvhZ).setDuration(1000).start();  
    }  

就这样就可以实现上面例子的效果。
最后再来说说anim的监听动画开始,结束,被取消,重复等事件的addListener方法

ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0.5f);  
    anim.addListener(new AnimatorListener()  
        {  

            @Override  
            public void onAnimationStart(Animator animation)  
            {  
                Log.e(TAG, "onAnimationStart");  
            }  

            @Override  
            public void onAnimationRepeat(Animator animation)  
            {  
                // TODO Auto-generated method stub  
                Log.e(TAG, "onAnimationRepeat");  
            }  

            @Override  
            public void onAnimationEnd(Animator animation)  
            {  
                Log.e(TAG, "onAnimationEnd");  
                ViewGroup parent = (ViewGroup) mBlueBall.getParent();  
                if (parent != null)  
                    parent.removeView(mBlueBall);  
            }  

            @Override  
            public void onAnimationCancel(Animator animation)  
            {  
                // TODO Auto-generated method stub  
                Log.e(TAG, "onAnimationCancel");  
            }  
        });  
        anim.start();  

有时候会觉得,我只要知道结束就行了,上面的代码有点长,那就使用AnimatorListenerAdapter

anim.addListener(new AnimatorListenerAdapter()  
{  
    @Override  
    public void onAnimationEnd(Animator animation)  
    {  
        Log.e(TAG, "onAnimationEnd");  
        ViewGroup parent = (ViewGroup) mBlueBall.getParent();  
        if (parent != null)  
            parent.removeView(mBlueBall);  
    }  
});  

Animation更详细内容参考,参考博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值