Cách thay đổi màu chỉ báo tiến trình của ProgressBar trong Android


178

Tôi đã đặt Ngang ProgressBar.

Tôi muốn thay đổi màu tiến độ sang màu vàng.

<ProgressBar 
    android:id="@+id/progressbar" 
    android:layout_width="80dip" 
    android:layout_height="20dip"  
    android:focusable="false" 
    style="?android:attr/progressBarStyleHorizontal" />

Vấn đề là, màu tiến độ là khác nhau trong các thiết bị khác nhau. Vì vậy, tôi muốn nó để sửa màu tiến độ.


câu trả lời ở trên thay đổi toàn bộ màu nền và điều mơ hồ là nó thay đổi chiều cao của thanh tiến trình thành rất tối đa. Không thể thay đổi trong xml. cách tốt hơn để chỉ thay đổi trạng thái thanh tiến trình là bao nhiêu đã hoàn thành là 20% màu đỏ, 50% màu vàng 70% và trên màu xanh lá cây. bạn có thể làm điều đó bằng lập trình trong java. chia sẻ câu trả lời của bạn nếu bạn có bất kỳ giải pháp nào khác
Mubashar 17/03/2017

Câu trả lời:


365

Tôi đã sao chép nó từ một trong những ứng dụng của mình, vì vậy sẽ có thêm một vài thuộc tính, nhưng sẽ cho bạn ý tưởng. Đây là từ bố trí có thanh tiến trình:

<ProgressBar
    android:id="@+id/ProgressBar"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:indeterminate="false"
    android:maxHeight="10dip"
    android:minHeight="10dip"
    android:progress="50"
    android:progressDrawable="@drawable/greenprogress" />

Sau đó tạo một drawable mới với một cái gì đó tương tự như sau (Trong trường hợp này greenprogress.xml):

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="5dip" />
            <gradient
                android:angle="270"
                android:centerColor="#ff5a5d5a"
                android:centerY="0.75"
                android:endColor="#ff747674"
                android:startColor="#ff9d9e9d" />
        </shape>
    </item>

    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <corners android:radius="5dip" />
                <gradient
                    android:angle="270"
                    android:centerColor="#80ffb600"
                    android:centerY="0.75"
                    android:endColor="#a0ffcb00"
                    android:startColor="#80ffd300" />
            </shape>
        </clip>
    </item>
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="5dip" />
                <gradient
                    android:angle="270"
                    android:endColor="#008000"
                    android:startColor="#33FF33" />
            </shape>
        </clip>
    </item>

</layer-list>

Bạn có thể thay đổi màu sắc khi cần thiết, điều này sẽ cung cấp cho bạn một thanh tiến trình màu xanh lá cây.


Và tôi cũng xóa android này: indeterminate = "false"
Nishant Shah

2
Làm ơn giúp tôi. Tôi cố gắng tạo greenproTHER.xml bằng cách sao chép mã của bạn nhưng đánh dấu Android Studio 0.4.6 <danh sách lớp> và lỗi "Danh sách thành phần phải được khai báo" tôi phải làm gì?
UmAnusorn

1
Có thể thay đổi màu sắc linh hoạt?
async

màu sắc có thể thay đổi tùy thuộc vào giá trị tiến độ hiện tại được xác định trong thanh thực tế không?
Jonathan

@Ryan Sẽ rất hữu ích để giải thích những gì android:id="@android:id/progress", android:id="@android:id/background"và đại diện android:id="@android:id/secondaryProgress"cho.
RustamG

103

Một giải pháp đơn giản hơn:

progess_drawable_blue

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
    <shape>
        <solid
                android:color="@color/disabled" />
    </shape>
</item>

<item
    android:id="@android:id/progress">
    <clip>
        <shape>
            <solid
                android:color="@color/blue" />
        </shape>
    </clip>
</item>

</layer-list>

1
ở đây @ màu / bị vô hiệu hóa là một màu tùy chỉnh
Nitin Saxena

2
Hoặc <solid android: color = "@ android: color / black" /> hoặc thậm chí <solid android: color = "# ff33b5e5" />
superarts.org 18/03/2016

2
Điều này là đủ android: indeterminateTint = "@ color / white" cho API
Lever

53

Chỉ cần tạo một phong cách trong values/styles.xml.

<style name="ProgressBarStyle">
    <item name="colorAccent">@color/greenLight</item>
</style>

Sau đó đặt phong cách này làm ProgressBarchủ đề của bạn .

<ProgressBar
    android:theme="@style/ProgressBarStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

và không quan trọng thanh tiến trình của bạn là ngang hoặc tròn. Đó là tất cả.


1
Wow, giải pháp đơn giản nhất, làm việc cho tôi. Tôi tự hỏi tại sao câu trả lời này có nhiều phiếu như vậy.
Pavel Shorokhov

38

Nếu bạn chỉ muốn thay đổi màu thanh tiến trình, bạn chỉ cần sử dụng bộ lọc màu trong phương thức onCreate () của Activity:

ProgressBar progressbar = (ProgressBar) findViewById(R.id.progressbar);
int color = 0xFF00FF00;
progressbar.getIndeterminateDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
progressbar.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);

Ý tưởng từ đây .

Bạn chỉ cần làm điều này cho các phiên bản kẹo mút. Trên Lollipop, bạn có thể sử dụng thuộc tính kiểu colorAccent.


Đối với SeekBarnó là như nhau, chỉ cần thêm cho API 16 : seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);. Điều này sẽ thay đổi màu sắc của ngón tay cái tròn đó.
Sufian

1
Gọi setColorFilter()trực tiếp trên drawable sẽ áp dụng màu sắc ở khắp mọi nơi. Vì đây là những gì tôi không cần, tôi chỉ gọi mutate()trên Drawable(ví dụ nhưseekBar.getThumb().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
Sufian

3
Tôi đã thấy giải pháp này ở nơi khác nhưng tất cả những gì nó làm (thử nghiệm trên thiết bị Gingerbread) là biến toàn bộ thanh tiến trình thành một màu, khiến nó không thể thấy tiến trình thực tế
Neil C. Obremski

@ NeilC.Obremski vâng, bạn đúng. Nó có thể là ROM cụ thể, hoặc có thể là phiên bản cụ thể. Tôi đã phải loại bỏ nó hoàn toàn. Hy vọng rằng chúng tôi sẽ sớm chuyển bản này trở lại các phiên bản Android cũ hơn (thông qua hỗ trợ lib).
Sufian

25

đối với API cấp 21 trở lên, chỉ cần sử dụng

android:progressBackgroundTint="@color/yourBackgroundColor"
android:progressTint="@color/yourColor"

6

Có 3 cách để giải quyết câu hỏi này:

  1. Cách điều chỉnh màu thanh tiến trình khai báo
  2. Cách điều chỉnh màu của thanh tiến trình theo chương trình, nhưng chọn màu từ các màu được xác định trước khác nhau được khai báo trước thời gian biên dịch
  3. Cách điều chỉnh màu của thanh tiến trình theo chương trình, và cũng tạo màu theo chương trình.

Đặc biệt, có rất nhiều nhầm lẫn xung quanh # 2 và # 3, như đã thấy trong các bình luận cho câu trả lời của amfcosta. Câu trả lời đó sẽ mang lại kết quả màu sắc không thể đoán trước bất cứ lúc nào bạn muốn đặt thanh tiến trình thành bất cứ thứ gì ngoại trừ màu chính, vì nó chỉ sửa đổi màu nền và khu vực "clip" của thanh tiến trình thực tế vẫn sẽ là lớp phủ màu vàng với độ mờ giảm. Ví dụ: sử dụng phương pháp đó để đặt nền thành màu tím đậm sẽ dẫn đến màu "clip" của thanh tiến trình có màu hồng nhạt điên rồ do trộn màu tím đậm và màu vàng thông qua việc giảm alpha.

Vì vậy, dù sao đi nữa, # 1 được trả lời hoàn hảo bởi Ryan và Štarke trả lời hầu hết số 3, nhưng đối với những người tìm kiếm một giải pháp hoàn chỉnh cho # 2 và # 3:


Cách điều chỉnh màu của thanh tiến trình theo chương trình, nhưng chọn màu từ màu được xác định trước được khai báo trong XML

res / drawable / my_proTHERbar.xml :

Tạo tệp này nhưng thay đổi màu sắc trong my_proTHER và my_secondsProTHER:

(LƯU Ý: Đây chỉ là một bản sao của tệp XML thực tế xác định SDK ProgressBar mặc định của Android, nhưng tôi đã thay đổi ID và Màu sắc. Bản gốc có tên là Progress_horizontal)

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@+id/my_progress_background">
    <shape>
        <corners android:radius="5dip" />
        <gradient
            android:startColor="#ff9d9e9d"
            android:centerColor="#ff5a5d5a"
            android:centerY="0.75"
            android:endColor="#ff747674"
            android:angle="270"
            />
    </shape>
</item>

<item android:id="@+id/my_secondaryProgress">
    <clip>
        <shape>
            <corners android:radius="5dip" />
            <gradient
                android:startColor="#80ff171d"
                android:centerColor="#80ff1315"
                android:centerY="0.75"
                android:endColor="#a0ff0208"
                android:angle="270"
                />
        </shape>
    </clip>
</item>

<item android:id="@+id/my_progress">
    <clip>
        <shape>
            <corners android:radius="5dip" />
            <gradient
                android:startColor="#7d2afdff"
                android:centerColor="#ff2afdff"
                android:centerY="0.75"
                android:endColor="#ff22b9ba"
                android:angle="270"
                />
        </shape>
    </clip>
</item>

Trong Java của bạn :

final Drawable drawable;
int sdk = android.os.Build.VERSION.SDK_INT;
    if(sdk < 16) {
        drawable =  ctx.getResources().getDrawable(R.drawable.my_progressbar);
    } else {
        drawable = ContextCompat.getDrawable(ctx, R.drawable.my_progressbar);
    }
progressBar.setProgressDrawable(drawable)

Cách điều chỉnh màu của thanh tiến trình theo chương trình và cũng tạo màu theo chương trình

EDIT: Tôi tìm thấy thời gian để giải quyết điều này đúng. Câu trả lời trước đây của tôi để lại điều này một chút mơ hồ.

Một ProgressBar được cấu thành như 3 Drawables trong LayerDrawable.

  1. Lớp 1 là nền
  2. Lớp 2 là màu tiến trình thứ cấp
  3. Lớp 3 là màu thanh tiến trình chính

Trong ví dụ dưới đây, tôi sẽ thay đổi màu của thanh tiến trình chính thành màu lục lam.

//Create new ClipDrawable to replace the old one
float pxCornerRadius = viewUtils.convertDpToPixel(5);
final float[] roundedCorners = new float[] { pxCornerRadius, pxCornerRadius, pxCornerRadius, pxCornerRadius, pxCornerRadius, pxCornerRadius, pxCornerRadius, pxCornerRadius };
ShapeDrawable shpDrawable = new ShapeDrawable(new RoundRectShape(roundedCorners, null, null));
shpDrawable.getPaint().setColor(Color.CYAN);
final ClipDrawable newProgressClip = new ClipDrawable(shpDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL);

//Replace the existing ClipDrawable with this new one
final LayerDrawable layers = (LayerDrawable) progressBar.getProgressDrawable();
layers.setDrawableByLayerId(R.id.my_progress, newProgressClip);

Ví dụ đó đặt nó thành một màu đơn sắc. Bạn có thể đặt nó thành màu gradient bằng cách thay thế

shpDrawable.getPaint().setColor(Color.CYAN);

với

Shader shader = new LinearGradient(0, 0, 0, progressBar.getHeight(), Color.WHITE, Color.BLACK, Shader.TileMode.CLAMP);
shpDrawable.getPaint().setShader(shader);

Chúc mừng.

-Cây thương


những gì viewUtils trong viewUtils.convertDpToPixel (5);
Nikos Hidalgo

1
Xin chào @NikosHidalgo - Bạn có thể thấy một phương pháp gần như giống hệt ở đây: stackoverflow.com/questions/12849366/ . Sự khác biệt duy nhất là tôi xây dựng ViewUtilstài liệu tham khảo của mình Context, để tôi không cần phải vượt qua Contextkhi gọiconvertDpToPixel()
lance.dolan

Cảm ơn bạn đã trả lời nhanh chóng, đặc biệt là một câu trả lời đã được đăng cách đây rất lâu!
Nikos Hidalgo

Haha, tôi thực sự phải căng não để nhớ: p
lance.dolan 11/07/19

4

Nếu bạn ở API cấp 21 trở lên, bạn có thể sử dụng các thuộc tính XML này:

<!-- For indeterminate progress bar -->
android:indeterminateTint="@color/white"
<!-- For normal progress bar -->
android:progressTint="@color/white"

3

Giải pháp đơn giản nhất mà tôi tìm ra là một cái gì đó như thế này:

<item name="colorAccent">@color/white_or_any_color</item>

Đặt ở trên trong styles.xmltập tin dưới res > valuesthư mục.

LƯU Ý: Nếu bạn sử dụng bất kỳ màu nhấn nào khác, thì các giải pháp trước đó sẽ phù hợp.

API 21 hoặc CAO


Đây là giải pháp tốt nhất. 100% liên quan đến câu hỏi. rất đơn giản
Pir Fahim Shah

3
final LayerDrawable layers = (LayerDrawable) progressBar.getProgressDrawable();
layers.getDrawable(2).setColorFilter(color,PorterDuff.Mode.SRC_IN);

1
Cố gắng thêm một chút giải thích cho câu trả lời của bạn. Mã chỉ trả lời được khuyến khích.
Alexei

Tôi muốn nhận được lời giải thích đằng sau chỉ số 2 trong getDrawable, nhưng ít nhất đây là giải pháp duy nhất hiệu quả với tôi, cảm ơn!
Nikos Hidalgo

2

Đối với bất cứ ai đang tìm cách làm điều đó theo chương trình:

    Drawable bckgrndDr = new ColorDrawable(Color.RED);
    Drawable secProgressDr = new ColorDrawable(Color.GRAY);
    Drawable progressDr = new ScaleDrawable(new ColorDrawable(Color.BLUE), Gravity.LEFT, 1, -1);
    LayerDrawable resultDr = new LayerDrawable(new Drawable[] { bckgrndDr, secProgressDr, progressDr });
    //setting ids is important
    resultDr.setId(0, android.R.id.background);
    resultDr.setId(1, android.R.id.secondaryProgress);
    resultDr.setId(2, android.R.id.progress);

Đặt id thành drawables là rất quan trọng và đảm bảo việc giữ giới hạn và trạng thái thực tế của thanh tiến trình


1

Các bạn đang thực sự làm tôi đau đầu. Những gì bạn có thể làm là làm cho danh sách lớp của bạn có thể vẽ được thông qua xml trước (có nghĩa là nền là lớp đầu tiên, có thể vẽ biểu thị tiến trình thứ cấp là lớp thứ hai và có thể vẽ khác biểu thị tiến trình chính là lớp cuối cùng), sau đó thay đổi màu trên mã bằng cách làm như sau:

public void setPrimaryProgressColor(int colorInstance) {
      if (progressBar.getProgressDrawable() instanceof LayerDrawable) {
        Log.d(mLogTag, "Drawable is a layer drawable");
        LayerDrawable layered = (LayerDrawable) progressBar.getProgressDrawable();
        Drawable circleDrawableExample = layered.getDrawable(<whichever is your index of android.R.id.progress>);
        circleDrawableExample.setColorFilter(colorInstance, PorterDuff.Mode.SRC_IN);
        progressBar.setProgressDrawable(layered);
    } else {
        Log.d(mLogTag, "Fallback in case it's not a LayerDrawable");
        progressBar.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
    }
}

Phương pháp này sẽ mang lại cho bạn sự linh hoạt tốt nhất khi đo lường mức có thể rút ra ban đầu của bạn trên xml, KHÔNG CÓ SỬA ĐỔI TRÊN CẤU TRÚC NÓ SAU, đặc biệt nếu bạn cần phải có thư mục màn hình tệp xml cụ thể, sau đó chỉ cần sửa đổi CHỈ MÀU thông qua mã. Không khởi tạo lại một ShapeDrawable mới từ đầu bất cứ điều gì.


1

Màu ProgressBar có thể được thay đổi như sau:

/res/values/colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorAccent">#FF4081</color>
</resources>

/res/values/styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorAccent">@color/colorAccent</item>
</style> 

onCreate:

progressBar = (ProgressBar) findViewById(R.id.progressBar);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
    Drawable drawable = progressBar.getIndeterminateDrawable().mutate();
    drawable.setColorFilter(ContextCompat.getColor(this, R.color.colorAccent), PorterDuff.Mode.SRC_IN);
    progressBar.setIndeterminateDrawable(drawable);
}

1

Tạo một tài nguyên có thể vẽ được nền mà bạn cần, trong trường hợp của tôi, tôi đã đặt tên cho nó là bg_custom_proTHERbar.xml

<?xml version="1.0" encoding="utf-8"?>

<item>
    <shape android:shape="rectangle" >
        <corners android:radius="5dp"/>

        <gradient
            android:angle="180"
            android:endColor="#DADFD6"
            android:startColor="#AEB9A3" />
    </shape>
</item>
<item>
    <clip>
        <shape android:shape="rectangle" >
            <corners android:radius="5dp" />

            <gradient
                android:angle="180"
                android:endColor="#44CF4A"
                android:startColor="#2BB930" />
        </shape>
    </clip>
</item>
<item>
    <clip>
        <shape android:shape="rectangle" >
            <corners android:radius="5dp" />

            <gradient
                android:angle="180"
                android:endColor="#44CF4A"
                android:startColor="#2BB930" />
        </shape>
    </clip>
</item>

Sau đó sử dụng nền tùy chỉnh này như

 <ProgressBar
                android:id="@+id/progressBarBarMenuHome"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="match_parent"
                android:layout_height="20dp"
                android:layout_marginStart="10dp"
                android:layout_marginEnd="10dp"
                android:layout_marginBottom="6dp"
                android:indeterminate="false"
                android:max="100"
                android:minWidth="200dp"
                android:minHeight="50dp"
                android:progress="10"
                android:progressDrawable="@drawable/bg_custom_progressbar" />

Nó hoạt động tốt với tôi


0

Trong xml:

<ProgressBar
                    android:id="@+id/progressBar"
                    style="?android:attr/progressBarStyleInverse"
                    android:layout_width="60dp"
                    android:layout_height="60dp"
                    android:layout_margin="@dimen/dimen_10dp"


                 android:indeterminateTint="@{viewModel.getComplainStatusUpdate(position)}"
                    android:indeterminate="true"
                    android:indeterminateOnly="false"
                    android:max="100"
                    android:clickable="false"
                    android:indeterminateDrawable="@drawable/round_progress"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

ViewModel:

fun getComplainStatusUpdate(position: Int):Int{

                val list = myAllComplainList!!.getValue()
                if (list!!.get(position).complainStatus.equals("P")) {
                  //  progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
                   // progressBar.setBackgroundResource(R.drawable.circle_shape)
                    return Color.RED
                } else if (list!!.get(position).complainStatus.equals("I")) {

                    return Color.GREEN
                } else {

                    return Color.GREEN
                }


return Color.CYAN
    }

0

Với Chất liệu Thư viện Linh kiện bạn có thể sử dụng ProgressIndicatorvới các app:indicatorColorthuộc tính để thay đổi màu sắc:

  <com.google.android.material.progressindicator.ProgressIndicator
      style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Determinate"
      app:indicatorColor="@color/..."
      app:indicatorWidth="..."
      app:trackColor="@color/..."
      />

nhập mô tả hình ảnh ở đây

Lưu ý : nó yêu cầu ít nhất là phiên bản 1.3.0-alpha01.

Với việc ProgressBarbạn có thể ghi đè màu bằng cách sử dụng:

<ProgressBar
    android:theme="@style/CustomProgressBarTheme"
    ..>

với:

<style name="CustomProgressBarTheme">
    <item name="colorAccent">@color/primaryDarkColor</item>
</style>

nhập mô tả hình ảnh ở đây


0

Nếu bạn muốn đặt màu tiến trình chính và phụ thành thanh tiến trình ngang theo chương trình trong Android thì hãy sử dụng đoạn trích bên dưới

int[][] states = new int[][] {
                        new int[] {-android.R.attr.state_checked},
                        new int[] {android.R.attr.state_checked},
                };

                int[] secondaryColor = new int[] {
                        context.getResources().getColor(R.color.graph_line_one),
                        Color.RED,
                };

                int[] primaryColor = new int[] {
                        context.getResources().getColor(R.color.middle_progress),
                        Color.BLUE,
                };
                progressbar.setProgressTintList(new ColorStateList(states, primaryColor));
                progressbar.setSecondaryProgressTintList(new ColorStateList(states, secondaryColor));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.