Android中的动画

来源:互联网 发布:淘宝宝贝综合排名 编辑:程序博客网 时间:2024/05/29 18:31

在android开发中,简单的加载数据显得画面过于单一,借助动画效果可以让我们的画面更多样化

Android系统提供了很多丰富的API去实现UI的动画,可将其划分为以下几类:
1.Tween Aniamtion(补间动画)            2.Property Animation(属性动画)             3.Frame Animation(逐帧动画)
Tween Animation分为四种:
Alpha:渐变透明度动画
Scale:渐变尺寸缩放动画
Translate:位置移动变换动画
Rotate:旋转动画
共同属性:
(1)duration:动画持续时间。单位:毫秒
(2)reaptCount:动画重复次数
(3)reaptMode:动画重复模式(值:倒序重复 REVERSE,顺序重复 RESTART)
(4)startOffset:动画之间的时间间隔
(5)fillAfter:设置为true,表示动画转化效果在动画结束后被应用
(6)fillBefore:设置为true,表示动画转化效果在动画开始前被应用
(7)interprolator:动画插入器(加速、减速插入器)
以上的共同属性都可以通过set方式进行设置。

Animation属性详解

xml属性java方法解释android:detachWallpapersetDetachWallpaper(boolean)是否在壁纸上运行android:durationsetDuration(long)动画持续时间,毫秒为单位android:fillAftersetFillAfter(boolean)控件动画结束时是否保持动画最后的状态android:fillBeforesetFillBefore(boolean)控件动画结束时是否还原到开始动画前的状态android:fillEnabledsetFillEnabled(boolean)与android:fillBefore效果相同android:interpolatorsetInterpolator(Interpolator)设定插值器(指定的动画效果,譬如回弹等)android:repeatCountsetRepeatCount(int)重复次数android:repeatModesetRepeatMode(int)重复类型有两个值,reverse表示倒序回放,restart表示从头播放android:startOffsetsetStartOffset(long)调用start函数之后等待开始运行的时间,单位为毫秒android:zAdjustmentsetZAdjustment(int)表示被设置动画的内容运行时在Z轴上的位置(top/bottom/normal),默认为normal
java类名xml关键字描述信息AlphaAnimation<alpha> 放置在res/anim/目录下渐变透明度动画效果RotateAnimation<rotate> 放置在res/anim/目录下画面转移旋转动画效果ScaleAnimation<scale> 放置在res/anim/目录下渐变尺寸伸缩动画效果TranslateAnimation<translate> 放置在res/anim/目录下画面转换位置移动动画效果AnimationSet<set> 放置在res/anim/目录下一个持有其它动画元素alpha、scale、translate、rotate或者其它set元素的容器
在android开发中,可发现很多功能的实现可分XML和javacode,动画的开发也不例外,也可通过两者来进行开发

XML中

alph渐变透明度动画效果scale渐变尺寸伸缩动画效果translate画面转换位置移动动画效果rotate画面转移旋转动画效果

 

 

 

XMl方式的实现是在res资产文件中创建anim文件来保存相应的xml文件

JavaCode中

AlphaAnimation渐变透明度动画效果ScaleAnimation渐变尺寸伸缩动画效果TranslateAnimation画面转换位置移动动画效果RotateAnimation画面转移旋转动画效果

 

 

 

 下面我们依次介绍下几种动画:

ImageView   iv = (ImageView)findViewById(R.id.iv);

1.Alpha渐变透明度动画效果

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <alpha
  3. android:fromAlpha="1.0"
  4. android:toAlpha="0.0"
  5. android:duration="500" />
  6. <!--
  7. fromAlpha:开始时透明度
  8. toAlpha: 结束时透明度
  9. duration:动画持续时间 -->
假设上面的文件是alpha.xml,则可通过java代码来加载此动画
  1. Animation alpha = AnimationUtils.loadAnimation(context,R.anim.alpha);
  2. iv.startAnimation(alpha);    或者      iv.setAnimation(alpha);       alpha.start();
AlphaAnimation
  1. AlphaAnimation alpha = new AlphaAnimation(0f,1f);
  2. alpha.setDuration(1000);   //动画单次播放时间
  3. iv.startAnimation(alpha);      或者     iv.setAnimation(alpha);          alpha.start();

2.Rotate画面旋转动画效果
在anim目录中创建rotate.xml文件
  1. <rotate xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:duration="1000"
  3. android:fromDegrees="0"
  4. android:pivotX="50%"
  5. android:pivotY="50%"
  6. android:toDegrees="360">
  7. </rotate>
  1. Animation rotate = AnimationUtils.loadAnimation(context,R.anim.rotate);
  2. iv.startAnimation(alpha);   或者    iv.setAnimation(rotate);       rotate.start();
   RotateAnimation
  1. RotateAnimation  rotate = 
  2. new RotateAnimation(0.0f, 350f, Animation.RELATIVE_TO_SELF, 0.5f ,Animation.RELATIVE_TO_SELF, 0.5f);
  3. iv.startAnimation(rotate);   或者   iv.setAnimation(rotate);        rotate.start();
对于旋转动画,需要了解下旋转的方向,from到to   有小到大   则控件是顺时针旋转
中心点的话,就看自己的设置,常用就是看设置中是相对于什么来取中心点

3.Transla画面转换位置移动动画效果
在anim目录中创建translate.xml文件

  1. <translate xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:fromXDelta="0"
  3. android:toXDelta="0"
  4. android:fromYDelta="100"
  5. android:toYDelta="100"
  6. android:duration="1000"
  7. </translate>
  1. Animation translate = AnimationUtils.loadAnimation(context,R.anim.translate);
  2. iv.startAnimation(translate);     或者     iv.setAnimation(translate);         translate.start();
    TranslateAnimation   
  1. TranslateAnimation translate = 
  2. new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f,
  3. Animation.RELATIVE_TO_SELF, 1f, Animation.RELATIVE_TO_SELF, 1f);
  4. translate.setDuration(1000);
  5. iv.startAnimation(translate);      或者     iv.setAnimation(translate);          translate.start();
说到平移动画,也要注意:可以看作控件的左上角就是基点,每次平移都是将这个点从指定的点移动到另一个点4.Scale 渐变尺寸缩放动画 在anim目录下创建scale.xml文件
  1. <scale xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:fromXScale="0"
  3. android:toXScale="1"
  4. android:fromYScale="0"
  5. android:toYScale="1"
  6. android:pivotX="50%"
  7. android:pivotY="50%"
  8. android:duration="1000"
  9. </scale>
  1. Animation scale = AnimationUtils.loadAnimation(context,R.anim.scale);
  2. iv.startAnimation(scale); 或者 iv.setAnimation(scale); scale.start();
ScaleAnimation
  1. ScaleAnimation scale = new ScaleAnimation(0f, 1f, 0f, 1f,
  2. Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
  3. scale.setDuration(1000);
  4. iv.startAnimaiton(scale); 或者 iv.setAnimation(scale); scale.start();

 Alpha属性详解

xml属性java方法解释android:fromAlphaAlphaAnimation(float fromAlpha, …)动画开始的透明度(0.0到1.0,0.0是全透明,1.0是不透明)android:toAlphaAlphaAnimation(…, float toAlpha)动画结束的透明度,同上

Rotate属性详解

xml属性java方法解释android:fromDegreesRotateAnimation(float fromDegrees, …)旋转开始角度,正代表顺时针度数,负代表逆时针度数android:toDegreesRotateAnimation(…, float toDegrees, …)旋转结束角度,正代表顺时针度数,负代表逆时针度数android:pivotXRotateAnimation(…, float pivotX, …)缩放起点X坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)android:pivotYRotateAnimation(…, float pivotY)缩放起点Y坐标,同上规律

Scale属性详解

xml属性java方法解释android:fromXScaleScaleAnimation(float fromX, …)初始X轴缩放比例,1.0表示无变化android:toXScaleScaleAnimation(…, float toX, …)结束X轴缩放比例android:fromYScaleScaleAnimation(…, float fromY, …)初始Y轴缩放比例android:toYScaleScaleAnimation(…, float toY, …)结束Y轴缩放比例android:pivotXScaleAnimation(…, float pivotX, …)缩放起点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)android:pivotYScaleAnimation(…, float pivotY)缩放起点Y轴坐标,同上规律

Translate属性详解

xml属性java方法解释android:fromXDeltaTranslateAnimation(float fromXDelta, …)起始点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)android:fromYDeltaTranslateAnimation(…, float fromYDelta, …)起始点Y轴从标,同上规律android:toXDeltaTranslateAnimation(…, float toXDelta, …)结束点X轴坐标,同上规律android:toYDeltaTranslateAnimation(…, float toYDelta)结束点Y轴坐标,同上规律

 AnimationSet详解

AnimationSet继承自Animation,是上面四种的组合容器管理类,没有自己特有的属性,他的属性继承自Animation,所以特别注意,当我们对set标签使用Animation的属性时会对该标签下的所有子控件都产生影响。

视图动画使用方法

通过上面对于动画的属性介绍之后我们来看看在Android中这些动画如何使用(PS:这里直接演示xml方式,至于java方式太简单了就不说了),如下:

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] >    <alpha  android:fromAlpha="float" android:toAlpha="float" />    <scale  android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" />    <translate  android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" />    <rotate  android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" />    <set>        ...    </set></set>
ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);spaceshipImage.startAnimation(hyperspaceJumpAnimation);

上面就是一个标准的使用我们定义的补间动画的模板。至于补间动画的使用,Animation还有如下一些比较实用的方法介绍:

Animation类的方法解释reset()重置Animation的初始化cancel()取消Animation动画start()开始Animation动画setAnimationListener(AnimationListener listener)给当前Animation设置动画监听hasStarted()判断当前Animation是否开始hasEnded()判断当前Animation是否结束

既然补间动画只能给View使用,那就来看看View中和动画相关的几个常用方法吧,如下:

View类的常用动画操作方法解释startAnimation(Animation animation)对当前View开始设置的Animation动画clearAnimation()取消当View在执行的Animation动画


插值器简介

介绍补间动画插值器之前我们先来看一幅图,如下:

这里写图片描述

可以看见其实各种插值器都是实现了Interpolator接口而已,同时可以看见系统提供了许多已经实现OK的插值器,具体如下:

java类xml id值描述AccelerateDecelerateInterpolator@android:anim/accelerate_decelerate_interpolator动画始末速率较慢,中间加速AccelerateInterpolator@android:anim/accelerate_interpolator动画开始速率较慢,之后慢慢加速AnticipateInterpolator@android:anim/anticipate_interpolator开始的时候从后向前甩AnticipateOvershootInterpolator@android:anim/anticipate_overshoot_interpolator类似上面AnticipateInterpolatorBounceInterpolator@android:anim/bounce_interpolator动画结束时弹起CycleInterpolator@android:anim/cycle_interpolator循环播放速率改变为正弦曲线DecelerateInterpolator@android:anim/decelerate_interpolator动画开始快然后慢LinearInterpolator@android:anim/linear_interpolator动画匀速改变OvershootInterpolator@android:anim/overshoot_interpolator向前弹出一定值之后回到原来位置PathInterpolator
新增,定义路径坐标后按照路径坐标来跑。

如上就是系统提供的一些插值器,下面我们来看看怎么使用他们。

2-5-2 插值器使用方法

插值器的使用比较简答,如下:

<set android:interpolator="@android:anim/accelerate_interpolator">    ...</set>

2-5-3 插值器的自定义

有时候你会发现系统提供的插值器不够用,可能就像View一样需要自定义。所以接下来我们来看看插值器的自定义,关于插值器的自定义分为两种实现方式,xml自定义实现(其实就是对现有的插值器的一些属性修改)或者java代码实现方式。如下我们来说说。

先看看XML自定义插值器的步骤:

  • 在res/anim/目录下创建filename.xml文件。
  • 修改你准备自定义的插值器如下:
<?xml version="1.0" encoding="utf-8"?><InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android" android:attribute_name="value" />
  • 在你的补间动画文件中引用该文件即可。

可以看见上面第二步修改的是现有插值器的一些属性,但是有些插值器却不具备修改属性,具体如下:

<accelerateDecelerateInterpolator>

无可自定义的attribute。

<accelerateInterpolator>

android:factor 浮点值,加速速率(默认值为1)。

<anticipateInterploator>

android:tension 浮点值,起始点后拉的张力数(默认值为2)。

<anticipateOvershootInterpolator>

android:tension 浮点值,起始点后拉的张力数(默认值为2)。
android:extraTension 浮点值,拉力的倍数(默认值为1.5)。

<bounceInterpolator>

无可自定义的attribute。

<cycleInterplolator>

android:cycles 整形,循环的个数(默认为1)。

<decelerateInterpolator>

android:factor 浮点值,减速的速率(默认为1)。

<linearInterpolator>

无可自定义的attribute。

<overshootInterpolator>

android:tension 浮点值,超出终点后的张力(默认为2)。

再来看看Java自定义插值器的(Java自定义插值器其实是xml自定义的升级,也就是说如果我们修改xml的属性还不能满足需求,那就可以选择通过Java来实现)方式。

可以看见上面所有的Interpolator都实现了Interpolator接口,而Interpolator接口又继承自TimeInterpolator,TimeInterpolator接口定义了一个float getInterpolation(float input);方法,这个方法是由系统调用的,其中的参数input代表动画的时间,在0和1之间,也就是开始和结束之间。

如下就是一个动画始末速率较慢、中间加速的AccelerateDecelerateInterpolator插值器:

public class AccelerateDecelerateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {    ......    public float getInterpolation(float input) {        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;    }    ......}

Frame Animation(逐帧动画):

       逐帧动画(Frame-by-frame Animations)从字面上理解就是一帧挨着一帧的播放图片,就像放电影一样。和补间动画一样可以通过xml实现也可以通过java代码实现。接下来借助目前项目中的一个开奖的动画来总结如何使用。实现效果如下:

具体实现过程:

1.)在res/drawable目录下一个文件lottery_animlist.xml,内容如下:

复制代码
<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android"    android:oneshot="false">    <item        android:drawable="@mipmap/lottery_1"        android:duration="200" />    <item        android:drawable="@mipmap/lottery_2"        android:duration="200" />    <item        android:drawable="@mipmap/lottery_3"        android:duration="200" />    <item        android:drawable="@mipmap/lottery_4"        android:duration="200" />    <item        android:drawable="@mipmap/lottery_5"        android:duration="200" />    <item        android:drawable="@mipmap/lottery_6"        android:duration="200" /></animation-list>
复制代码

根节点是animation-list(动画列表),里面有一个或者多个item节点组成,oneshot属性表示是否只播放一次,true表示只会播放一次,false表示一直循环播放,内部用item节点声明一个动画帧,android:drawable指定此帧动画所对应的图片资源,android:druation代表此帧持续的时间,整数,单位为毫秒。

注意:

   之前使用eclipse或者Android ADT开发的时候,文件可以放在res/anim和res/drawable两个文件夹下面,虽然谷歌推荐放在res/drawable文件夹下但是不会报错,在使用Android studio时候就没那么幸运了,如果不放在res/drawable文件夹下面会报如下错误:

2.)用ImageView控件作为动画载体来显示动画

复制代码
 <ImageView   android:id="@+id/animation_iv"   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:layout_gravity="center"   android:layout_margin="10dp"   android:src="@drawable/lottery_animlist" />
复制代码

这个时候我们运行一下,发现动画没有运行而是停留在第一帧,那是因为AnimationDrawable播放动画是依附在window上面的,而在Activity onCreate方法中调用时Window还未初始化完毕,所有才会停留在第一帧,要想实现播放必须在onWindowFocusChanged中添加如下代码:

imageView.setImageResource(R.drawable.lottery_animlist);AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable();animationDrawable.start();

如果想要停止播放动画可以调用AnimationDrawable的stop方法

  imageView.setImageResource(R.drawable.lottery_animlist);  AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable();  animationDrawable.stop();

3.)纯Java代码实现方式

复制代码
AnimationDrawable anim = new AnimationDrawable();    for (int i = 1; i <= 6; i++) {    int id = getResources().getIdentifier("lottery_" + i, "mipmap", getPackageName());    Drawable drawable = getResources().getDrawable(id);    anim.addFrame(drawable, 200);    }    anim.setOneShot(false);    imageView.setImageDrawable(anim);    anim.start();
复制代码

4.)AnimationDrawable 几个常见的api

  • void start() - 开始播放动画

  • void stop() - 停止播放动画

  • addFrame(Drawable frame, int duration) - 添加一帧,并设置该帧显示的持续时间

  • void setOneShoe(boolean flag) - false为循环播放,true为仅播放一次

  • boolean isRunning() - 是否正在播放

总结:

   Frame Animation(逐帧动画)相对来说比较简单,但是在实际开发中使用的频率还是比较高的。希望以这个小例子能够掌握逐帧动画,但是逐帧动画只能实现比较小的动画效果,如果复杂而且帧数比较多的动画不太建议使用逐帧动画,一方面是因为会造成OOM,另一方面会显得很卡,如果真是超级复杂的动画的话建议选择双缓冲绘制View来实现。








0 0
原创粉丝点击