菜鸟集中营,android的三种动画基础用法。

来源:互联网 发布:马云说的阿里健康 编辑:程序博客网 时间:2024/05/18 01:19

  android动画中的常用的三种动画,即逐帧动画(FrameAnimation),补间动画(TweenAnimation)和属性动画(PropertyAniation).

  首先就最简单的FramAnimation入手,看看如何分别用代码和xml文件实现。

  如果是将动画定义在xml文件中,无论是哪一种动画,只要定义在xml文件中,我们都需要去在res目录下创建一个anima的folder用于存储和读取定义的xml文件。

FrameAnimation的资源类型为drawable,标签类型为animation-list(ps:套图自己找,名字自己取)

<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android"  android:oneshot="false">  <item android:drawable="@drawable/f1" android:duration="300" />  <item android:drawable="@drawable/f2" android:duration="300" />  <item android:drawable="@drawable/f3" android:duration="300" />  <item android:drawable="@drawable/f4" android:duration="300" /></animation-list>
oneshot的值有两个true/false,表示动画是否重复。

至此xml中的部分就完成了,只需要在代码中初始化某一控件后(多为ImageView)添加设置动画就可以了

 image = (ImageView) findViewById(R.id.frame_image);    image.setBackgroundResource(R.anim.frame);    AnimationDrawable anim = (AnimationDrawable) image.getBackground();    anim.start();
以上是设置ImageView的背景,当然也可以直接设置成图片资源,效果都是一样的。
 image.setImageResource(R.drawable.animation2);   animationDrawable = (AnimationDrawable) animationIV.getDrawable();   animationDrawable.start();

此时结束,动画还是没能显示,出现这种现象是因为当我们在onCreate中调用AnimationDrawable的start方法时,窗口Window对象

还没有完全初始化,AnimationDrawable不能完全追加到窗口Window对象中,那么该怎么办呢?我们需要把这段代码放在

onWindowFocusChanged方法中,当Activity展示给用户时,onWindowFocusChanged方法就会被调用,我们正是在这个时候实现

我们的动画效果。当然,onWindowFocusChanged是在onCreate之后被调用的。当然如果是将代码写入一个点击监听或者触摸监听

内,就没这么多事了。

   接下来看一看如何用代码进行逐帧动画的实现,其实也很简单

AnimationDrawable ad = new AnimationDrawable();for (int i = 1; i <= 4; i++) {  int resourcesId = getResources().getIdentifier(imageName(图片的名字), "drawable", getPackageName());  Drawable drawable = getResources().getDrawable(resourceId);  anim.addFrame(drawable, 300);}anim.setOneShot(false);image.setBackgroundDrawable(anim);或者:image.setImageResource(anim); anim.start();

 接下来我们来看一看补间动画(TweenAnimation).

补间动画又叫做View Animation,正如其名一样,它只能对View和继承View的控件视图进行操作,而且操作也是视图上的,是一系

列View形状的变换,如大小的缩放,透明度的改变,位置的改变,真实的属性是不会发生改变的,各个动画效果之间可以连用,但

不会有影响,关于这一点,讲到属性动画是会进行对比的。

首先我们来看一下,如何使用xml文件进行补间动画的设置。

资源标签为<TweenAnimaton>元素标签有五个,分别是<alpha>,<translation>,<rotate>,<scale>和<set>.

AlphaAnimation:透明度(alpha)渐变效果,对应<alpha/>标签。

TranslateAnimation:位移渐变,需要指定移动点的开始和结束坐标,对应<translate/>标签。

ScaleAnimation:缩放渐变,可以指定缩放的参考点,对应<scale/>标签。

RotateAnimation:旋转渐变,可以指定旋转的参考点,对应<rotate/>标签。

AnimationSet:组合渐变,支持组合多种渐变效果,对应<set/>标签。

可以通过startOffset属性设置 各个动画的开始偏移(开始时间)来达到动画顺序播放的效果。

可以通过设置interpolator属性改变动画渐变的方式,

如AccelerateInterpolator,开始时慢,然后逐渐加快。默认为AccelerateDecelerateInterpolator。


我从别人的博客截取了一张表,大家自己看:

博客地址:http://blog.csdn.net/qq_34381084/article/details/52228017

Interpolator的介绍

AccelerateDecelerateInterpolator在动画开始与介绍的地方速率改变比较慢,在中间的时候加速AccelerateInterpolator在动画开始的地方速率改变比较慢,然后开始加速CycleInterpolator动画循环播放特定的次数,速率改变沿着正弦曲线DecelerateInterpolator在动画开始的地方速率改变比较慢,然后开始减速LinearInterpolator在动画的以均匀的速率改变


这里为了方便起见就一个set标签搞定了,不多说,上代码:

<set xmlns:android="http://schemas.android.com/apk/res/android"          android:interpolator="@android:anim/decelerate_interpolator"          android:shareInterpolator="true" >                <scale              android:duration="2000"              android:fromXScale="0.2"              android:fromYScale="0.2"              android:pivotX="50%"              android:pivotY="50%"              android:toXScale="1.5"              android:toYScale="1.5" />                <rotate              android:duration="1000"              android:fromDegrees="0"              android:repeatCount="1"              android:repeatMode="reverse"              android:toDegrees="360" />                <translate              android:duration="2000"              android:fromXDelta="0"              android:fromYDelta="0"              android:toXDelta="320"              android:toYDelta="0" />                <alpha              android:duration="2000"              android:fromAlpha="1.0"              android:toAlpha="0.1" />      </set>  

代码控件设置就ok了。

Animation a=AnimationUtil.loadAnimation(R.drawable.name);

image.startAnimation(a);


接下来是代码单纯代码设置动画,简单粗暴。

AnimationSet set = new AnimationSet(true);AlphaAnimation alphaAnimation=new AlphaAnimation(fromAlpha, toAlpha);set.addAnimation(alpha);animationSet.setFillBefore(true);animationSet.setFillAfter(false);animationSet.setDuration(200);ImageView.startAnimation(animationSet);


好了,最后是相对用的比较多的PropertyAnimation了。属性动画是android3.0以后推出的动画类型,他的出现弥补了补间动画的不

足之处,属性动画对于控件属性的设置更改是真实的修改,而不仅仅是对于View的绘制,如果顺序播放几个动画效果,是会互相影

响的。属性动画的作用对象不仅仅局限于View和其子类控件,就说一点,他的作用对象是object你就知道他的作用范围有多广了。

好的,菜鸟集中营,我们从头说起:


属性动画中最核心的一个类ValuAnimator
ValueAnimator:

属性动画的运行机制是通过不断地对值进行操作来实现的,

而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的.

只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长,

那么ValueAnimator就会自动完成从初始值平滑地过渡到结束值这样的效果。

ValueAnimator还负责管理动画的播放次数、播放模式、以及对动画设置监听器等,确实是一个非常重要的类。

ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);  anim.setDuration(300);  anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {      @Override      public void onAnimationUpdate(ValueAnimator animation) {          float currentValue = (float) animation.getAnimatedValue();          Log.d("TAG", "cuurent value is " + currentValue);      }  });  anim.start(); 
通过log你可以清楚的看到animation值的变化过程。


ofFloat()方法当中允许传入多个float类型的参数,这里传入0和1就表示将值从0平滑过渡到1,

然后调用ValueAnimator的setDuration()方法来设置动画运行的时长,最后调用start()方法启动动画。

借助监听器可以记录属性动画的运行效果。

当然也许你并不需要小数位数的动画过渡,可能你只是希望将一个整数值从0平滑地过渡到100,

那么也很简单,只需要调用ValueAnimator的ofInt()方法就可以了

ValueAnimator anim = ValueAnimator.ofInt(0, 100);

可以调用setStartDelay()方法来设置动画延迟播放的时间


调用setRepeatCount()和setRepeatMode()方法来设置动画循环播放的次数以及循环播放的模式,

循环模式包括RESTART和REVERSE两种,分别表示重新播放和倒序播放的意思



ObjectAnimator:可以直接对任意对象的任意属性进行动画操作
ObjectAnimator会更加常用一些,但是它其实是继承自ValueAnimator的,底层的动画实现机制也是基于ValueAnimator来完成的

 ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);      animator.setDuration(5000);      animator.start();  
将一个TextView在5秒中内从常规变换成全透明,再从全透明变换成常规

这里第一个参数要求传入一个object对象,想要对哪个对象进行动画操作就传入什么,这里传入了一个textview。

第二个参数是想要对该对象的哪个属性进行动画操作,改变TextView的不透明度,因此这里传入"alpha"。

后面的参数就是不固定长度了,想要完成什么样的动画就传入什么值,

这里传入的值就表示将TextView从常规变换成全透明,再从全透明变换成常规。

之后调用setDuration()方法来设置动画的时长,然后调用start()方法启动动画

ObjectAnimator内部的工作机制并不是直接对我们传入的属性名进行操作的,而是会去寻找这个属性名对应的get和set方法


组合动画

实现组合动画功能主要需要借助AnimatorSet这个类,这个类提供了一个play()方法,

如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,

AnimatorSet.Builder中包括以下四个方法:

    after(Animator anim)   将现有动画插入到传入的动画之后执行

    after(long delay)   将现有动画延迟指定毫秒后执行

    before(Animator anim)   将现有动画插入到传入的动画之前执行

    with(Animator anim)   将现有动画和传入的动画同时执行



Animator监听器-----AnimatorListener();

监听到动画的各种事件,比如动画何时开始,何时结束,然后在开始或者结束的时候去执行一些逻辑处理

Animator类当中提供了一个addListener()方法,这个方法接收一个AnimatorListener,

我们只需要去实现这个AnimatorListener就可以监听动画的各种事件了。

anim.addListener(new AnimatorListener() {          @Override          public void onAnimationStart(Animator animation) {          }                @Override          public void onAnimationRepeat(Animator animation) {          }                @Override          public void onAnimationEnd(Animator animation) {          }                @Override          public void onAnimationCancel(Animator animation) {          }      });  
onAnimationStart()方法会在动画开始的时候调用,

onAnimationRepeat()方法会在动画重复执行的时候调用,

onAnimationEnd()方法会在动画结束的时候调用,

onAnimationCancel()方法会在动画被取消的时候调用。

Android提供了一个适配器类,叫作AnimatorListenerAdapter

anim.addListener(new AnimatorListenerAdapter() {  

    });  

那么如果我想监听动画结束这个事件,就只需要单独重写这一个方法就可以了



使用XML编写动画:通过XML来完成和代码一样的属性动画功能

通过XML来编写动画可能会比通过代码来编写动画要慢一些,但是在重用方面将会变得非常轻松

然后在XML文件中的propertyAnimation资源标签下,我们一共可以使用如下三种标签:

    <animator>  对应代码中的ValueAnimator

    <objectAnimator>  对应代码中的ObjectAnimator

    <set>  对应代码中的AnimatorSet


比如说我们想要实现一个从0到100平滑过渡的动画,在XML当中就可以这样写:

 <animator xmlns:android="http://schemas.android.com/apk/res/android"          android:valueFrom="0"          android:valueTo="100"          android:valueType="intType"/>  
而如果我们想将一个视图的alpha属性从1变成0,就可以这样写:

 <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"          android:valueFrom="1"          android:valueTo="0"          android:valueType="floatType"          android:propertyName="alpha"/>  
最后在代码中添加设置控件代码和补间动画一样,就不在重复了。


最后是几个注意事项:

alpha动画的从无到有是(0f,1f)

scale缩放分为X轴和Y轴,值的大小设置与alpha类似

rotate为翻转,参数值为度数,所以如果设置的和alpha和scale相似就看不出什么效果了

translation 为平移,分为X轴和Y轴,,参数为正向下移动,参数未负向上移动,代码中参数的设置为px,同样小了看不出效果

动画是可以组合的,如果scale设置的参数为(1f,0f);那么后面的动画就看不出任何效果了,应为属性在scale这里就缩没有了。

最后贴一段onClickListener,去掉中间的break,你会发现神奇的效果。

@Overridepublic void onClick(View v) {switch(v.getId()){case R.id.bt_alpha:ObjectAnimator al=ObjectAnimator.ofFloat(tv, "alpha", 0f,1f,0f,1f);al.setDuration(2000);al.start();case R.id.bt_scaleX:ObjectAnimator sx=ObjectAnimator.ofFloat(tv, "scaleX", 0f,2f,4f,1f);sx.setDuration(2000);sx.start();case R.id.bt_scaleY:ObjectAnimator sy=ObjectAnimator.ofFloat(tv, "scaleY", 0f,2f,4f,1f);sy.setDuration(2000);sy.start();case R.id.bt_translationX:ObjectAnimator tx=ObjectAnimator.ofFloat(tv, "translationX", 0f,100f,-200f,0f);tx.setDuration(2000);tx.start();case R.id.bt_translationY:ObjectAnimator ty=ObjectAnimator.ofFloat(tv, "translationY", 0f,100f,-200f,0f);ty.setDuration(2000);ty.start();//沿着中心转---tween中是左上角转默认情况不一样case R.id.bt_rotation:ObjectAnimator ro=ObjectAnimator.ofFloat(tv, "rotation", 0f,360f,-360f,0f);ro.setDuration(2000);ro.start();break;case R.id.bt_other:break;}}


1 0
原创粉丝点击