Android動畫合輯之幀動畫


本節引言:

從本節開始我們來探究Android中的動畫,畢竟在APP中加入一些動畫,會讓我們的應用變得 很炫,例如最簡單的關開Activity,當然自訂控制動畫肯定必不可少啦~而Android中的動畫 分為三大類,逐幀動畫(Frame)以及補間動畫(Tween),還有Android 3.0以後引入的屬性動畫 (Property),而本節帶給大家的是第一種動畫-逐幀動畫的一個基本使用~1.gif


1.幀動畫概念以及用法

幀動畫非常容易理解,其實就是簡單的由N張靜態圖片收集起來,然後我們透過控制依序顯示 這些圖片,因為人眼"視覺殘留"的原因,會讓我們造成動畫的"錯覺",跟放電影的原理一樣!

而Android中實作幀動畫,一般我們會用到前面講解到的一個Drawable:AnimationDrawable先寫好Drawable,然後程式碼中呼叫start()以及stop()開始或停止播放動畫~

當然我們也可以在Java程式碼中建立逐幀動畫,建立AnimationDrawable對象,然後調用 addFrame(Drawable frame,int duration)在動畫中加入幀,接著呼叫start()和stop()而已~

#下面我們來寫兩個例子體會下幀動畫的效果以及熟悉下用法


2.使用範例:

範例一:最簡單的範例

執行效果圖

2.gif

程式碼實作

#先寫我們的動畫文件,非常簡單,先在res下方建立一個anim目錄,接著開始擼我們的 動畫檔案:miao_gif.xml: 這裡的android:oneshot是設定動畫是否只是播放一次,true只播放一次,false循環播放!

<?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/img_miao1"
        android:duration="80" />
    <item
        android:drawable="@mipmap/img_miao2"
        android:duration="80" />
    <item
        android:drawable="@mipmap/img_miao3"
        android:duration="80" />
    <!--限于篇幅,省略其他item,自己补上-->
    ...</animation-list>

動畫檔案有了,接著到我們的佈局檔案:activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开始" />

    <Button
        android:id="@+id/btn_stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止" />

    <ImageView
        android:id="@+id/img_show"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_gravity="center"
        android:background="@anim/miao_gif" />
    </LinearLayout>

最後是我們的MainActivity.java,這裡在這裡控制動畫的開始以及暫停:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btn_start;
    private Button btn_stop;
    private ImageView img_show;
    private AnimationDrawable anim;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindViews();
        anim = (AnimationDrawable) img_show.getBackground();
    }

    private void bindViews() {
        btn_start = (Button) findViewById(R.id.btn_start);
        btn_stop = (Button) findViewById(R.id.btn_stop);
        img_show = (ImageView) findViewById(R.id.img_show);
        btn_start.setOnClickListener(this);
        btn_stop.setOnClickListener(this);
    }
    
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_start:
                anim.start();
                break;
            case R.id.btn_stop:
                anim.stop();
                break;
        }
    }
}

好的,非常的簡單哈~


範例二:在指定地方播放幀動畫

#執行效果圖

3.gif

程式碼實作

依舊是先上我們的動畫檔案:anim_zhuan.xml

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item
        android:drawable="@mipmap/img_zhuan1"
        android:duration="80" />
    <item
        android:drawable="@mipmap/img_zhuan2"
        android:duration="80" />
    <item
        android:drawable="@mipmap/img_zhuan3"
        android:duration="80" />
     <!--限于篇幅,省略其他item,自己补上-->
    ...</animation-list>

接著我們來寫一個自訂的ImageView:FrameView.java,這裡透過反射來獲得目前播放的幀, 然後是否為最後一幀,是的話隱藏控制!

/**
 * Created by Jay on 2015/11/15 0015.
 */
public class FrameView extends ImageView {

    private AnimationDrawable anim;

    public FrameView(Context context) {
        super(context);
    }

    public FrameView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FrameView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setAnim(AnimationDrawable anim){
        this.anim = anim;
    }

    public void setLocation(int top,int left){
        this.setFrame(left,top,left + 200,top + 200);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        try{
            //反射调用AnimationDrawable里的mCurFrame值
            Field field = AnimationDrawable.class
                    .getDeclaredField("mCurFrame");
            field.setAccessible(true);
            int curFrame = field.getInt(anim);// 获取anim动画的当前帧
            if (curFrame == anim.getNumberOfFrames() - 1)// 如果已经到了最后一帧
            {
                //让该View隐藏
                setVisibility(View.INVISIBLE);
            }
        }catch (Exception e){e.printStackTrace();}
        super.onDraw(canvas);
    }
}

最後是我們的MainActivity.java,建立一個FrameLayout,加入View,對觸控事件中按下的 事件做處理,顯示控制項以及開啟動畫~

public class MainActivity extends AppCompatActivity {

    private FrameView fView;
    private AnimationDrawable anim = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FrameLayout fly = new FrameLayout(this);
        setContentView(fly);
        fView = new FrameView(this);
        fView.setBackgroundResource(R.anim.anim_zhuan);
        fView.setVisibility(View.INVISIBLE);
        anim = (AnimationDrawable) fView.getBackground();
        fView.setAnim(anim);
        fly.addView(fView);
        fly.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                //设置按下时才产生动画效果
                if(event.getAction() == MotionEvent.ACTION_DOWN){
                    anim.stop();
                    float x = event.getX();
                    float y = event.getY();
                    fView.setLocation((int) y - 40,(int)x-20);  //View显示的位置
                    fView.setVisibility(View.VISIBLE);
                    anim.start();    //开启动画
                }
                return false;
            }
        });
    }
}

好的,同樣很簡單哈~


3.本節範例程式碼和Gif影格擷取工具下載

AnimationDemo1.zip

AnimationDemo2.zip

#Gif訊框擷取工具


本節小結:

#好的,本節給大家介紹了一下Android三種動畫中最簡單的幀動畫,實際開發用的並不多 不過學多點東西,以後也多個想法嘛~好的,本節就到這裡,謝謝~

#