首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 動畫閃爍問題:XML 載入 vs 程式碼建立 TranslateAnimation 差異分析

     編輯:程式設計綜合問答

現象

使用 AnimationUtils.loadAnimation() 載入 XML 定義的平移動畫會閃爍;改用程式碼 `new TranslateAnimation(...)` 則正常。

程式碼對比

XML 方式 (閃爍)

<translate xmlns:android="..."
    android:duration="2000"
    android:fillAfter="true"
    android:fromXDelta="0%" android:toXDelta="-100%" />
Animation anim = AnimationUtils.loadAnimation(ctx, R.anim.xxx);
image.startAnimation(anim);

程式碼方式 (正常)

TranslateAnimation ta = new TranslateAnimation(
    Animation.RELATIVE_TO_SELF, 0f,
    Animation.RELATIVE_TO_SELF, -1f,
    Animation.RELATIVE_TO_SELF, 0f,
    Animation.RELATIVE_TO_SELF, 0f);
ta.setDuration(2000);
ta.setFillAfter(true);
image.startAnimation(ta);

根本原因

  1. XML 解析時機:`loadAnimation` 每次呼叫都會重新解析 XML、建立 `Animation` 物件,若在 `onCreate`/`onResume` 重複呼叫會疊加動畫導致閃爍。
  2. fillAfter 行為差異:XML `android:fillAfter="true"` 僅影響動畫結束後視圖矩陣,不改變 Layout 參數;程式碼若搭配 `setFillAfter(true)` 行為一致,但開發者常在程式碼中額外處理 `setAnimationListener` 移除動畫或切換可見性。
  3. 硬體加速衝突:XML 動畫可能觸發 View 硬體層建立,若 View 未設 `setLayerType(LAYER_TYPE_HARDWARE)` 會在動畫開始/結束時閃爍。

解決方案

  • 複用 Animation 物件:在 `onCreate` 中一次 `loadAnimation` 並持有引用,後續直接 `startAnimation(cachedAnim)`。
  • 啟用硬體層:動畫前 `view.setLayerType(View.LAYER_TYPE_HARDWARE, null)`,動畫結束 `onAnimationEnd` 裡 `view.setLayerType(View.LAYER_TYPE_NONE, null)`。
  • 改用 ViewPropertyAnimator (API 12+):
image.animate().translationX(-image.getWidth()).setDuration(2000).withEndAction(() -> {
    image.setVisibility(View.GONE);
}).start();

更簡潔、效能更好、不易閃爍。

吐槽提醒

單一動畫無需包裝在 `AnimationSet` 中,直接用 `TranslateAnimation` 或 `ViewPropertyAnimator` 即可。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved