Android动画机制(1):帧动画、补间动画详解及实战演练

Android动画机制(1):帧动画、补间动画详解及实战演练

 

 作者:

 蒋东国                                                                                         

 时间:

 2017年03月05日 星期日

 应用来源:

 无

 博客地址:

 http://blog.csdn.net/andrexpert/article/details/60480009

      

       情景再现“Android目前包含四种动画:Property Animation、View Animation、Drawable Animation、SVG,其中,属性动画被引入于Android 3.0,它可应用于任何对象;视图动画包含旋转、缩放、移动、透明度动画效果,但只适用于View;SVG矢量动画被引入与Android5.0,通过SVG可以创建更加丰富的动画效果。”

 

1.  逐帧动画(Drawable Animation)

      逐帧动画是利用了人眼的视觉暂留特性,通过依次显示多张静态图片达到播放动画的效果。定义逐帧动画非常简单,只要在< animation-list../>元素中使用<item…/>子元素定义动画的全部帧,并指定各帧的持续时间。举例如下:

<animation-listxmlns:android="http://schemas.android.com/apk/res/android"
   android:oneshot="false" >
    <item android:drawable="@drawable/progress_loading_image_01"android:duration = "80"/>
    <item android:drawable="@drawable/progress_loading_image_02"android:duration = "80"/>
    <item android:drawable="@drawable/progress_loading_image_03"android:duration = "80"/>
    <item android:drawable="@drawable/progress_loading_image_04"android:duration = "80"/>
</animation-list>

       其中,android:oneshot属性用于控制动画是否循环播放。当然,Android也支持在Java代码中使用AnimationDrawable对象,并调用addFrame(Drawable frame,int duration)向该动画中添加一帧。对XML文件的使用如下:

       ImageView mIvLoading =(ImageView) findViewById(R.id.iv_xiaomei);
       mIvLoading.setBackgroundResource(R.drawable.animlist_loading_progess);  
       AnimationDrawablemAnim = (AnimationDrawable) mIvLoading.getBackground();
       mAnim.start();

示例:仿美团数据加载动画效果


 

2.  补间动画(View Animation)

(1)  缩放动画

     视图缩放动画表示View以(pivotX, pivotY),它在XML文件中用< scale./>属性标识,其Java层对应的类为ScaleAnimation。

 <scale xmlns:android="http://schemas.android.com/apk/res/android"
   android:interpolator="@[package:]anim/interpolator_resource"
        android:fromXScale="float"
       android:toXScale="float"
       android:fromYScale="float"
       android:toYScale="float"
       android:duration="int"
       android:fillAfter="boolean"
       android:pivotX="float"
       android:pivotY="float"/>

       其中,android:interpolator属性用于指定动画播放的速度类型,比如android:interpolator=@android:anim/linear_interpolator"表示缩放动画匀速进行;android:fromX(Y)Scale、android:toX(Y)Scale属性用于指定View在X或Y方向上缩放比例的起止大小,以1.0表示View正常大小;android:pivotX、android:pivotY属性用于指定View进行缩放时的轴中心,比如值分别为50、50时表示以View所在的父组件布局的50%位置为缩放的轴中心,若值分别为50%、50%时表示表示以View自身所在布局区域的50%位置(即View的中心位置)为缩放的轴中心; android:duration属性用于指定动画持续的时间,单位为ms;android:fillAfter属性用于指定view缩放之后的状态,true表示保持view缩放之后的状态。对于的Java代码实现如下:

ScaleAnimationscaleAnim = new ScaleAnimation(0, 1, 0, 1,        //从无缩放大到正常大小
Animation.RELATIVE_TO_SELF,0.5F,                                       //以view自身中点为轴中心
Animation.RELATIVE_TO_SELF,0.5F);
scaleAnim.setInterpolator(newLinearInterpolator());                     //匀速播放
scaleAnim.setDuration(1000);                                                         //持续1s
scaleAnim.setFillAfter(true);                                                           //保持缩放之后的效果
view.startAnimation(scaleAnim);

(2)  移动动画

        视图移动动画表示View在垂直或水平方向进行位置移动,它在XML文件中用< translate ./>属性标识,其Java层对应的类为TranslateAnimation。View的移动动画支持三种数据格式:-100%~100%表示移动的距离以view自身尺寸大小为基准;-100%p~100%p表示移动的距离以view所在的父组件尺寸大小为基准;任意无含%后缀浮点值(如float x)表示移动的距离为相对以view当前位置为原点移动的大小x(dp)。

<translate xmlns:android="http://schemas.android.com/apk/res/android"
     android:interpolator="@[package:]anim/interpolator_resource"
     android:fromXDelta="float"
     android:toXDelta="float"
     android:fromYDelta="float"
     android:toYDelta="float"
     android:duration="int"
     android:fillAfter="boolean" />

       其中,android:fromXDelta、android:toXDelta属性用于指定view在X轴方向上的移动起止位置,比如android:fromXDelta=”0%”、 android:toXDelta="50%"表示view从原点向右移动view水平方向尺寸大小的一半距离,android:fromXDelta=”0%p”、 android:toXDelta="50%p"表示view从原点向右移动view所在父组件水平方向尺寸大小的一半距离,android:fromXDelta=”0”、 android:toXDelta="50"表示view从原点向右移动50dp;android:fromYDelta、android:toYDelta属性用于指定view在Y轴方向上的移动起止位置,设置方法同X轴。对于的Java代码实现如下:

TranslateAnimationtranslateAnimation = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT,0,          //x方向以view父容器的50%大小向右移动
Animation.RELATIVE_TO_PARENT,50,        //y方向相对原始位置向下移动100dp
Animation.ABSOLUTE,0, Animation.ABSOLUTE, 100);
translateAnimation.setInterpolator(newLinearInterpolator());//匀速播放
translateAnimation.setDuration(1000);                                    //持续1s
translateAnimation.setFillAfter(true);                                      //保持移动之后的效果
view.startAnimation(translateAnimation);

(3)  旋转动画

       视图旋转动画表示View相对于轴中心(pivotX,pivotY)旋转的角度,它在XML文件中用< rotate.../>属性标识,其Java层对应的类为RotateAnimation。View的旋转动画角度范围-360度~360度,其中0度表示保持不变;旋转的轴中心(pivotX, android:pivotY)的值可用三种不同的形式设置:如果为浮点数坐标(x,y),表示轴中心为相对于view左边缘以外的dp距离;如果为(x%,y%),表示轴中心相对于view左边缘以内的大小百分比;如果为(x%p,y%p),表示轴中心为相对于view父容器左边缘的大小百分百。

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
   android:interpolator="@[package:]anim/interpolator_resource"
   android:fromDegrees="float"
   android:toDegrees="float"
   android:pivotX="float"
   android:pivotY="float"
   android:duration="int"
   android:fillAfter="boolean"/>

     其中,android:fromDegrees、android:toDegrees属性用于指定view旋转的起止角度;android:pivotX、android:pivotY=属性用于指定view旋转时的轴中心。对于Java代码实现为:

RotateAnimationrotateAnimation = new RotateAnimation(0,
360,Animation.RELATIVE_TO_SELF, 50,  //以view的中心为轴中心旋转360度
Animation.RELATIVE_TO_SELF,50);
rotateAnimation.setInterpolator(newLinearInterpolator());    //匀速播放
rotateAnimation.setDuration(1000);                                         //持续1s
rotateAnimation.setFillAfter(true);                                           //保持缩放之后的效果
view.startAnimation(rotateAnimation);

(4)  淡入淡出动画

视图淡入淡出动画通过修改view的透明度实现淡入淡出的效果,它在XML文件中用<alpha.../>属性标识,其Java层对应的类为AlphaAnimation。View的透明度设置范围为0~1,其中0表示完全透明,1表示完全不透明。

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
            android:interpolator="@[package:]anim/interpolator_resource"
       android:fromAlpha="float"
       android:toAlpha="float"
       android:duration="int"
       android:fillAfter="boolean"/>

     其中,android:fromAlpha、android:toAlpha属性用于指定view的起止透明度,比如android:fromAlpha=”0.5”、 android:toAlpha=”1.0”表示view从半透明状态变化到完全不透明状态。对于Java代码实现为:

AlphaAnimationalphaAnimation = new AlphaAnimation(0.5f, 1.0f);
alphaAnimation.setInterpolator(newLinearInterpolator());            //匀速播放
alphaAnimation.setDuration(1000);                                                //持续1s
alphaAnimation.setFillAfter(true);                                                  //保持缩放之后的效果
view.startAnimation(alphaAnimation);

3. 实战演练-奔跑中的小美

     除了单独的给view增加旋转、移动、缩放、淡出淡入动画,Android还提供了<set../>标签属性实现几种动画的混合使用,该XML属性对应的Java类为AnimationSet。为了演示不同动画的混合使用,我们写这么一个Demo:在仿美团数据加载动画的基础上,我们让小美先原地旋转360度,然后匀速奔跑屏幕的一半宽度的长度,最后再加速奔跑同时逐渐消失。

(1)  res/anim/anim_xiaomei.xml

<?xml version="1.0"encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
   android:fillAfter="true"
   android:shareInterpolator="false" >
 
    <!—顺时针旋转360度 -->
   <rotate
       android:duration="1000"
       android:fromDegrees="0"
       android:pivotX="50%"
       android:pivotY="50%"
       android:toDegrees="360" />
       <!-然后,向右移动父容器的50%宽度(距离) ->
   <translate
       android:duration="2000"
       android:fillAfter="true"
       android:fromXDelta="0%p"
       android:fromYDelta="0%p"
       android:interpolator="@android:anim/linear_interpolator"
       android:startOffset="1000"
       android:toXDelta="50%p"
       android:toYDelta="0%p" />
    <!—然后,加速同时逐渐消失 -->
    <set
       android:interpolator="@android:anim/decelerate_interpolator"
        android:startOffset="2000" >
       <alpha
           android:duration="1500"
           android:fillAfter="true"
           android:fromAlpha="1.0"
           android:toAlpha="0" />
 
       <translate
           android:duration="1500"
           android:fillAfter="true"
           android:fromXDelta="0"
           android:fromYDelta="0"
           android:toXDelta="50%p"
           android:toYDelta="0" />
   </set>
</set>

       其中,android:shareInterpolator属性用于指定所有子标签的动画是否使用相同的速度;android:startOffset属性用于设定该动画是否延迟执行,如果希望不同的动画能够依次能够执行,那么当前动画延迟执行的时间应该是上一个动画执行的时间。

(2) AnimationTweenActivity.class

/**
 * 奔跑中的小美
 *
 * @author Created by jiangdongguoon 2017-3-5下午2:25:57
 */
public class AnimationTweenActivity extends Activity {
       private AnimationDrawablemAnim;
       private ImageView mIvLoading;
       private Button mBtnRunning;
 
       @Override
       protected void onCreate(BundlesavedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.anim_tween_activity);
              mIvLoading =(ImageView) findViewById(R.id.iv_xiaomei);
              mIvLoading.setBackgroundResource(R.drawable.animlist_loading_progess);
              final Animation animation= AnimationUtils.loadAnimation(this, R.anim.anim_xiaomei);
              //注册动画事件监听器
              animation.setAnimationListener(newAnimationListener() {
                     @Override
                     public voidonAnimationStart(Animation animation) {
 
                     }
 
                     @Override
                     public voidonAnimationRepeat(Animation animation) {
 
                     }
 
                     @Override
                     public voidonAnimationEnd(Animation animation) {
                            mBtnRunning.setText("预备,砰.....");
                            mAnim.stop();
                     }
              });
              // 获得AnimationDrawable
              mAnim =(AnimationDrawable) mIvLoading.getBackground();
 
              mBtnRunning = (Button)findViewById(R.id.btn_action_running);
              mBtnRunning.setOnClickListener(newOnClickListener() {
                     @Override
                     public voidonClick(View v) {
                            mIvLoading.startAnimation(animation);
                            mBtnRunning.setText("停止");
                            mAnim.start();
                     }
              });
       }
}

(3) 效果演示


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值