• Android中动画学习


    Android中动画学习 - Dufresne - 博客园

    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="http://schemas.android.com/apk/res/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="http://schemas.android.com/apk/res/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<AnimationDrawable> 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);
        }
    }
    复制代码

    废话不说了,具体需要可以下载这个例子,包括基本的基础动画的使用。

     代码下载地址: http://files.cnblogs.com/bastard/animationTest.rar

  • 相关阅读:
    【hdu4057】 恨7不成妻
    【hdu3709】 Balanced Number
    【hdu3555】 Bomb
    【hdu2809】 不要62
    【bzoj3992】 SDOI2015—序列统计
    【uoj125】 NOI2013—书法家
    【bzoj1833】 ZJOI2010—count 数字计数
    【bzoj1026】 SCOI2009—windy数
    【bzoj2780】 Sevenk Love Oimaster
    【bzoj3930】 CQOI2015—选数
  • 原文地址:https://www.cnblogs.com/seven1979/p/4386206.html
Copyright © 2020-2023  润新知