Androidのフレームごとのアニメーションの理解と使用

20258 ワード

概要
名前の通り、フレーム単位のアニメーションは、画像リソースのセットをフレーム単位で再生し、フレーム単位のアニメーションは、補間アニメーションと同様にXMLまたはJavaコードで実現することができます.もちろんどのような方法で実現してもAnimationDrawableクラスのサポートは欠かせませんが、このクラスを理解してみましょう.
AnimationDrawable
まず、プロパティ定義を見てみましょう.
 	<declare-styleable name="AnimationDrawable">
        <attr name="visible" />
        <attr name="variablePadding" />
        <!-- If true, the animation will only run a single time and then
             stop.  If false (the default), it will continually run,
             restarting at the first frame after the last has finished. -->
             //   true  ,             ,   false              ,   false
             //         xml animation-list             setOneShot(boolean oneShot)    
        <attr name="oneshot" format="boolean" />
    </declare-styleable>

    <!-- Represents a single frame inside an AnimationDrawable. -->
    <declare-styleable name="AnimationDrawableItem">
        <!-- Amount of time (in milliseconds) to display this frame. -->
        //            
        <attr name="duration" format="integer" />
        <!-- Reference to a drawable resource to use for the frame.  If not
             given, the drawable must be defined by the first child tag. -->
             //          
        <attr name="drawable" format="reference" />
    </declare-styleable>

よく使われるいくつかの方法:
  • void start()アニメーションの再生を開始
  • void stop()アニメーションの再生を停止
  • boolean isRunning()現在のAnimationDrawableが
  • を再生しているかどうかを判断する
  • int getNumberOfFrames()すべてのフレーム数
  • を取得
  • Drawable getFrame(int index)指定フレームに対応するDrawableオブジェクト
  • を取得する.
  • int getDuration(int i)指定フレームの表示期間
  • を取得する.
  • boolean isOneShot()は、現在のAnimationDrawableがtrueをループ実行するか否かを判断し、falseループ実行
  • を表す.
  • void setOneShot(boolean oneShot)AnimationDrawableが
  • をループ実行するかどうかを設定
  • void addFrame(@NonNull Drawable frame,int duration)AnimationDrawableにフレーム
  • を追加
    具体的な使用
    具体的に使ってみましょう.まずxmlで実現します.
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
       android:oneshot="true">
    
       <item android:drawable="@drawable/img0" android:duration="100"/>
       <item android:drawable="@drawable/img1" android:duration="100"/>
       <item android:drawable="@drawable/img2" android:duration="100"/>
       <item android:drawable="@drawable/img3" android:duration="100"/>
       <item android:drawable="@drawable/img4" android:duration="100"/>
       <item android:drawable="@drawable/img5" android:duration="100"/>
      //       item                   
    </animation-list>
    

    次に、xmlファイルでImageViewのandroid:src/android:backgroundプロパティを直接設定して使用するか、コードで設定することもできます.
        <ImageView
            android:id="@+id/iv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/frame_anim"
            android:layout_gravity="center"/>
    

    コードからアニメーションを開始
    		//    android:background ,  AnimationDrawable      
            final AnimationDrawable animationDrawable = (AnimationDrawable) iv.getBackground();
            
            //    android:src ,  AnimationDrawable      
            //AnimationDrawable animationDrawable = (AnimationDrawable) iv.getDrawable();
    
    		btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    animationDrawable.start();
                }
            });
            
            btn2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    animationDrawable.stop();
                }
            });
    

    ここで注意したいのは、android:oneshotをtrueに設定すると、アニメーションが1回再生された後、再びアニメーションを再生する必要があります.この場合、stop()メソッドを呼び出してからstart()を呼び出す必要があります.そうしないと、最後のフレームに止まります.効果図:javaコード実装:
            final AnimationDrawable animationDrawable = new AnimationDrawable();
            animationDrawable.setOneShot(true);
            for (int i = 0; i <= 83; i++) {
                int id = getResources().getIdentifier("img" + i, "drawable", getPackageName());
                Drawable drawable = getResources().getDrawable(id);
                animationDrawable.addFrame(drawable, 100);
            }
            iv.setBackground(animationDrawable);
            
    		btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    animationDrawable.start();
                }
            });
            
            btn2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    animationDrawable.stop();
                }
            });
    

    ここでは、ファイル名で対応するリソースidを取得する方法について簡単に説明します.
    /**
         * Return a resource identifier for the given resource name.  A fully
         * qualified resource name is of the form "package:type/entry".  The first
         * two components (package and type) are optional if defType and
         * defPackage, respectively, are specified here.
         * 
         * 

    Note: use of this function is discouraged. It is much more * efficient to retrieve resources by identifier than by name. * * @param name The name of the desired resource. * @param defType Optional default resource type to find, if "type/" is * not included in the name. Can be null to require an * explicit type. * @param defPackage Optional default package to find, if "package:" is * not included in the name. Can be null to require an * explicit package. * * @return int The associated resource identifier. Returns 0 if no such * resource was found. (0 is not a valid resource ID.) */

    public int getIdentifier(String name, String defType, String defPackage) { return mResourcesImpl.getIdentifier(name, defType, defPackage); }

    最初のパラメータはファイル名で、2番目のパラメータはリソースが存在するファイルタイプで、3番目のパラメータはパッケージ名です.特に、フレームごとのアニメーションを使用する場合は、OOMが発生しないように、大きなサイズの画像を使用しないでください.これでフレームごとのアニメーションの紹介が終わりました.ありがとうございます.