Chinaunix首页 | 论坛 | 博客
  • 博客访问: 266781
  • 博文数量: 170
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1709
  • 用 户 组: 普通用户
  • 注册时间: 2014-05-06 18:01
文章分类

全部博文(170)

文章存档

2016年(11)

2015年(130)

2014年(29)

分类: Android平台

2016-02-26 20:03:05

Android中动画:

  1. Tween Animation:通过对场景里的对象不断做图像变换(平移、缩放、旋转)产生动画效果,即是一种渐变动画;
  2. Frame Animation:顺序播放事先做好的图像,是一种画面转换动画。

把这两种动画中的的各种用法整理了一下,具体代码在附件中。如下图:

 

   

 

     

 

下面看下这两种动画的使用:

 

 Tween Animation

 Tween Animation有四种形式:

  l  alpha              渐变透明度动画效果

  l  scale                渐变尺寸伸缩动画效果

  l  translate            画面位置移动动画效果

  l  rotate                 画面旋转动画效果

 

  这四种动画实现方式都是通过Animation类和AnimationUtils配合实现。

可以通过xml实现:动画的XML文件在工程中res/anim目录。

  例如:rotate.xml

 

复制代码
xml version="1.0" encoding="utf-8"?> <set xmlns:android="" android:fillAfter = "false" android:zAdjustment="bottom" > <rotate android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" android:duration="4000" /> set>
复制代码

 

实现动画 

复制代码
Animation anim = AnimationUtils.loadAnimation(mContext, R.anim.rotate); //监听动画的状态(开始,结束) anim.setAnimationListener(new EffectAnimationListener());
textWidget = (TextView)findViewById(R.id.text_widget);
textWidget.setText(" 画面转移旋转动画效果");
textWidget.startAnimation(anim);
复制代码

 

  具体使用方法就不用介绍了很简单,每种形式的使用方法和效果可以见附件例子中。

 

 Frame Animation

  Frame Animation是顺序播放事先做好的图像,跟电影类似。不同于animation package,

Android SDK提供了另外一个类AnimationDrawable来定义使用Frame Animation。

 

利用xml文件实现:res/drawable-hdpi/frame.xml:

 

复制代码
xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="" android:oneshot="true" > <item android:drawable="@drawable/p1" android:duration="1000">item> <item android:drawable="@drawable/p2" android:duration="1000">item> <item android:drawable="@drawable/p3" android:duration="1000">item> <item android:drawable="@drawable/p4" android:duration="1000">item> <item android:drawable="@drawable/p5" android:duration="1000">item> <item android:drawable="@drawable/p6" android:duration="1000">item> animation-list>
复制代码

 

实现动画:      

复制代码
AnimationDrawable anim = (AnimationDrawable)getResources().

getDrawable(R.drawable.frame); CustomAnimDrawable cusAnim = new CustomAnimDrawable(anim);
cusAnim.setAnimationListener(new FrameAnimationListener());
textWidget = (TextView)findViewById(R.id.text_widget);
textWidget.setText(" 画面逐帧动画效果");
textWidget.setBackgroundDrawable(anim);
cusAnim.start();
复制代码

 

  这里有点不同的是,利用AnimationDrawable实现动画时,本身并没有提供接口来监听动画的状态(开始,结束),

这里我自己简单实现了一个方法来判断动画的状态。CustomAnimDrawable是自己写的继承于AnimationDrawable的

一个类,用来根据播放第几帧来判断,避免了根据时间来判断时,理论时间和实际时间不一致造成的影响。

  用到了Java的反射机制。

 CustomAnimDrawable实现:

复制代码
public class CustomAnimDrawable extends AnimationDrawable { private final String TAG = "xmp"; private AnimationDrawable mOriAnim; private AnimationDrawable mSelf; private Handler mHandler; private boolean mStarted; private AnimEndListenerRunnable mEndRunnable; private AnimationDrawableListener mListener; public CustomAnimDrawable(AnimationDrawable anim) {
        mOriAnim = anim;
        initialize();
    } private void initialize() {
        mSelf = this;
        mStarted = false;
        mHandler = new Handler();
        mEndRunnable = new AnimEndListenerRunnable(); for (int i = 0; i < mOriAnim.getNumberOfFrames(); i++) {
            mSelf.addFrame(mOriAnim.getFrame(i), mOriAnim.getDuration(i));
        }
    }

    @Override public void start() {
        mOriAnim.start();
        mStarted = true;
        mHandler.post(mEndRunnable); if (mListener != null) {
            mListener.onAnimationStart(mSelf);
        }
        Log.v(TAG, "------CustomAnimDrawable------>start");
    } /** * 循环检测 动画的状态 */ class AnimEndListenerRunnable implements Runnable {
        @Override public void run() { // 动画已开始 if (!mStarted) { return;
            } // 未停止继续监听 if (!isEnd()) {
          //这里的延迟时间是跟你的每一帧动画时间有关,基本保持一致就可以,最后一帧也会完整播放           //上面动画时间为每一帧1000ms,所以这里设为了1000ms mHandler.postDelayed(mEndRunnable,1000); return;
            }
            Log.v(TAG, "----------->over"); // 动画已结束 if (mListener != null) {
                mStarted = false;
                mListener.onAnimationEnd(mSelf);
            }
        }
    } /** * 判断动画是否结束 采用反射机制
     * @return */ private boolean isEnd(){
        Class animClass = AnimationDrawable.class; try{ //利用Java反射方法判断是否结束 //获得私有方法  例如 //Method method = animClass.getDeclaredMethod("nextFrame",boolean.class); //访问其私有变量 Field field = animClass.getDeclaredField("mCurFrame");
            field.setAccessible(true); int currFrameNum = field.getInt(mOriAnim); int totalFrameNum = mOriAnim.getNumberOfFrames(); if((currFrameNum == totalFrameNum - 1)|| (currFrameNum == -1)){ return true;
            }
        } catch (Exception e) {
            Log.v(TAG,"-------->Exception");
        } return false;
    } public void setAnimationListener(AnimationDrawableListener listener) {
        mListener = listener;
    } public interface AnimationDrawableListener { /** * Notifies the start of the animation
         * @param animation */ public void onAnimationStart(AnimationDrawable animation); /** * Notifies the end of the animation
         * @param animation */ public void onAnimationEnd(AnimationDrawable animation);
    }
}
复制代码

 

阅读(780) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~