2019年10月23日 星期三

[Android]訊息系統更新UI動態換圖&ObjectAnimator 實作

UI動態換圖教學
換圖步驟如下,
若有大量序列圖可用for迴圈配合陣列儲存序列圖的id
private int engineCircleViewId[] = new int[30];

在onCreate階段使用自訂函式init將所有序列圖找到並儲存
for(int i=0; i<=29; i++)
{
        Log.d(LOG_TAG, "speedCircleViewId[" + i + "] = " + speedCircleViewId[i]);
        engineCircleViewId[i] = getResources().getIdentifier("engine_speed_pointer_" + i, "drawable", "com.example.apkname");
}

再需要更新UI的地方 呼叫對應所引的drawable id並將其更新
circle_speed_pointer.setImageResource(speedCircleViewId[i]);

序列圖更新需要暫用相當大的資源加上更新UI需要時間,可配合訊息系統更新UI,以下為訊息系統宣告與實作方式

訊息系統實作
訊息ID宣告
private static final int MESG_CLUSTER_DIGITAL_FADE_OUT = 500;private static final int MESG_CLUSTER_DIGITAL_FADE_IN = 501;private static final int MESG_CLUSTER_ANALOG_FADE_OUT = 502;private static final int MESG_CLUSTER_ANALOG_FADE_IN = 503;

private ClusterSpeedometerValueMsgHandler clSpeedometerValueMsgHandler = null;

onCreate階段宣告message handler
clSpeedometerValueMsgHandler = new ClusterSpeedometerValueMsgHandler();

宣告function
private final class ClusterSpeedometerValueMsgHandler extends Handler{
    @Override    public void handleMessage(Message msg) {
        switch (msg.what) {
            case MESG_SPEEDOMETER_VALUE_UPDATE:
                updateSpeedometer_value(msg.arg1);                break;            case MESG_SPEEDOMETER_CIRCLE_UPDATE:
                updateSpeedometerCircle(msg.arg1);                break;        } }}


其中,宣告updateSpeedometerCircle(msg.arg1); 此行即呼應前一部分所宣告的updateSpeedometerCircle更新

ObjectAnimator 實作
相關引用類別函式庫
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;


接著直接在要變換的function裡面呼叫即可
public void func1()
{
     AnimatorSet animatorSet = new AnimatorSet(); //新增animator set
     animatorSet.setInterpolator(new DecelerateInterpolator()); //設定屬性
     ObjectAnimator ScreenFadeIn, SCALE_IN_X, SCALE_IN_Y; //宣告動畫物件ScreenFadeIn與SCAL_IN_X及Y


//透過case 分流或直接作以下動畫
     ScreenFadeIn = ObjectAnimator.ofFloat(mctlayout_main, View.ALPHA, 0.0f, 1.0f);
     SCALE_IN_X = ObjectAnimator.ofFloat(mctlayout_main, View.SCALE_X, 1.2f, 1.0f);
     SCALE_IN_X.setDuration(300);
     SCALE_IN_Y = ObjectAnimator.ofFloat(mctlayout_main, View.SCALE_Y, 1.2f, 1.0f);
     SCALE_IN_Y.setDuration(300);
     animatorSet.play(ScreenFadeIn).with(SCALE_IN_X).with(SCALE_IN_Y);//設定完以後用play with串起來,其中比較需要注意的是動畫間的Duration時間必須相等,若不相等則需要使用訊息系統更新UI去呼叫另一個Animator

//下面為增加Listener並透過animatorSet.start()啟動
animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
            }
        });
        animatorSet.start();//透過animatorSet.start()啟動

}

收工~

沒有留言:

張貼留言