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

Android 進度條顏色自訂:純程式碼實作 LayerDrawable 方案

     編輯:程式設計綜合問答

在 Android 中自訂水平進度條(ProgressBar)顏色,雖然常透過 XML layer-list 定義,但若需在執行期動態改變顏色(如依據下載狀態、主題切換),則必須使用純 Java/Kotlin 程式碼建構 LayerDrawable。

XML 參考架構(理解層級結構)

進度條由三層疊加組成:

  1. @android:id/background:背景軌道
  2. @android:id/secondaryProgress:次要進度(如緩衝進度)
  3. @android:id/progress:主要進度
<layer-list xmlns:android="https://schemas.android.com/apk/res/android">
  <item android:id="@android:id/background">
    <shape>
      <corners android:radius="5dp" />
      <gradient android:startColor="#ff9d9e9d" android:centerColor="#ff5a5d5a" android:endColor="#ff747674" android:angle="270" />
    </shape>
  </item>
  <item android:id="@android:id/secondaryProgress">
    <clip>
      <shape>
        <corners android:radius="5dp" />
        <gradient android:startColor="#80ffd300" android:centerColor="#80ffb600" android:endColor="#a0ffcb00" android:angle="270" />
      </shape>
    </clip>
  </item>
  <item android:id="@android:id/progress">
    <clip>
      <shape>
        <corners android:radius="5dp" />
        <gradient android:startColor="@color/progress_start" android:endColor="@color/progress_end" android:angle="270" />
      </shape>
    </clip>
  </item>
</layer-list>

純程式碼動態建構 LayerDrawable

public LayerDrawable createProgressDrawable(int bgStart, int bgCenter, int bgEnd,
                                           int secStart, int secCenter, int secEnd,
                                           int progStart, int progEnd) {
    // 1. 背景層
    ShapeDrawable bgShape = new ShapeDrawable(new RoundRectShape(new float[]{5,5,5,5,5,5,5,5}, null, null));
    bgShape.getPaint().setShader(new LinearGradient(0, 0, 0, 100, 
        new int[]{bgStart, bgCenter, bgEnd}, null, Shader.TileMode.CLAMP));

    // 2. 次要進度層
    ShapeDrawable secShape = new ShapeDrawable(new RoundRectShape(new float[]{5,5,5,5,5,5,5,5}, null, null));
    secShape.getPaint().setShader(new LinearGradient(0, 0, 0, 100,
        new int[]{secStart, secCenter, secEnd}, null, Shader.TileMode.CLAMP));
    ClipDrawable secondary = new ClipDrawable(secShape, Gravity.LEFT, ClipDrawable.HORIZONTAL);

    // 3. 主要進度層
    ShapeDrawable progShape = new ShapeDrawable(new RoundRectShape(new float[]{5,5,5,5,5,5,5,5}, null, null));
    progShape.getPaint().setShader(new LinearGradient(0, 0, 0, 100,
        new int[]{progStart, progEnd}, null, Shader.TileMode.CLAMP));
    ClipDrawable progress = new ClipDrawable(progShape, Gravity.LEFT, ClipDrawable.HORIZONTAL);

    // 4. 組合 LayerDrawable
    Drawable[] layers = {bgShape, secondary, progress};
    LayerDrawable layerDrawable = new LayerDrawable(layers);
    layerDrawable.setId(0, android.R.id.background);
    layerDrawable.setId(1, android.R.id.secondaryProgress);
    layerDrawable.setId(2, android.R.id.progress);
    return layerDrawable;
}

套用至 ProgressBar

ProgressBar progressBar = findViewById(R.id.progressBar);
LayerDrawable drawable = createProgressDrawable(
    0xFF9D9E9D, 0xFF5A5D5A, 0xFF747674,   // 背景漸層
    0x80FFD300, 0x80FFB600, 0xA0FFCB00,   // 次要進度漸層
    0xFF00FF00, 0xFF008800                // 主要進度漸層
);
progressBar.setProgressDrawable(drawable);

關鍵提醒

  • ID 必須對應:setId() 必須使用 android.R.id.background、secondaryProgress、progress,否則 ProgressBar 無法正確對應層級。
  • ClipDrawable 方向:水平進度條需設定 Gravity.LEFT 與 ClipDrawable.HORIZONTAL。
  • 效能考量:頻繁變色時建議快取 LayerDrawable 實例,避免重複建構物件。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved