歡迎介面想做出廣告頁自動輪播的效果,圖片切換的方式用淡入淡出的方式。這個在h5頁面很容易就實現了,但是在android介面中,很容易就想到了動畫animation動畫來實現,但是發現使用動畫的話,這種方式看起來不會自然,因為在呼叫statAnimation的時候因為圖片已經顯示了,這樣再硬生生的播放一次動畫其實會導致細微的閃爍效果。後來發現android中自帶了TransitionDrawable類可以很輕鬆地實現這個效果,但是會有侷限性。。。
先上效果圖:
這裡寫圖片描述

一、兩張圖片的切換效果,輕鬆實現

//講需要切換的兩張圖片直接給TransitionDrawable物件
TransitionDrawable transitionDrawable = new TransitionDrawable(new Drawable[]{getResources().getDrawable(R.drawable.advertiseone),getResources().getDrawable(R.drawable.advertisetwo)});
//一樣用
imgAdvertise.setImageDrawable(transitionDrawable);
//切換圖片的時間間隔
transitionDrawable.startTransition(3000);

二、切換多張圖片
實現思路,通過開啟一個執行緒(死迴圈),每隔一段時間傳送訊息到UI主執行緒中替換主執行緒中的transitionDrawable物件中的圖片就可以了,需要用到handler。這裡實現在廣告倒計時中無限迴圈圖片切換的次數

package com.coofond.carservice;

import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.coofond.carservice.mine.ui.LoginAct;

/**
 * Created by IBM on 2016/10/7.
 */

public class WelcomeAct extends AppCompatActivity {
    private TextView tvTimecount;
    private ImageView imgAdvertise;
    private int adTime = 6000;//倒計時秒數
    private int timeInterval = 1000;//倒計時間隔
    private CountDownTimer mTimer;//計時器
    private int change = 0;//記錄下標
    private int[] ids = new int[]{R.drawable.advertiseone, R.drawable.advertisetwo, R.drawable.advertisethree};
    private Drawable[] drawables;//圖片集合
    private Thread mThread;//執行緒
    private boolean mThreadFlag = true;//執行緒結束標誌符

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_welcome);
        initView();
        initData();
        initEvent();
    }

    //定義hander
    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            int duration = msg.arg1;
            TransitionDrawable transitionDrawable = new TransitionDrawable(new Drawable[]{drawables[change % ids.length],
                    drawables[(change + 1) % ids.length]});
            change++;//改變標識位置
            imgAdvertise.setImageDrawable(transitionDrawable);
            transitionDrawable.startTransition(duration);
            return false;
        }
    });

    //開啟執行緒傳送訊息,讓transition一直在改變
    private class MyRunnable implements Runnable {
        @Override
        public void run() {
            //這個while(true)是做死迴圈
            while (mThreadFlag) {
                int duration = 1000;//改變的間隔
                Message message = mHandler.obtainMessage();
                message.arg1 = duration;
                mHandler.sendMessage(message);
                try {
                    Thread.sleep(duration);
                    //隔duration秒傳送一次
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void initView() {
        tvTimecount = (TextView) findViewById(R.id.tv_advert);
        imgAdvertise = (ImageView) findViewById(R.id.iv_advetise);
        //填充圖片
        drawables=new Drawable[ids.length];
        for (int i = 0; i < ids.length; i++) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                drawables[i] = getDrawable(ids[i]);
            } else {
                drawables[i] = getResources().getDrawable(ids[i]);
            }
        }
    }
    private void initData() {
        // 初始化計時器,第一個引數是共要倒計時的秒數,第二個引數是倒計時的間隔
        mTimer = new CountDownTimer(adTime, timeInterval) {
            // 倒計時開始時要做的事情,引數m是直到完成的時間
            @Override
            public void onTick(long millisUntilFinished) {
                tvTimecount.setText("" + millisUntilFinished / 1000 + "s跳過廣告");
            }
            // 結束計時後要做的工作
            @Override
            public void onFinish() {
                jumpActivity();
            }
        };
        //開啟計時器
        mTimer.start();
        //開啟執行緒,改變transition,切換圖片
        mThread= new Thread(new MyRunnable());
        mThread.start();
    }

    private void initEvent() {
        tvTimecount.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mTimer.cancel();
                jumpActivity();
            }
        });
    }

    // 跳轉頁面
    private void jumpActivity() {
        //如果還沒結束當前的頁面,就結束
        if (!isFinishing()) {
            finish();
        }
        Intent it = new Intent(WelcomeAct.this, LoginAct.class);
        startActivity(it);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //mThread.stop(); 不推薦使用
        mThreadFlag=false;//結束執行緒

    }
}

記錄個小tips:如何比較優雅地結束一個執行緒,只要在while條件中設定自己識別符號,在需要結束的地方把識別符號改為false就可以了。基礎補上。。。

總結:transitionDrawable是切換兩張圖片淡入淡出效果的一個類。如果要切換多張圖片,那麼就相當於不斷替換它的膠捲就可以了。因為交卷在UI主執行緒就準備好了,所以需要用到handler進行通訊,然後開啟執行緒輪詢。因為實現的是廣告歡迎頁,倒計時一般只有3-5s,所以輪詢的次數也不會太多。

.