Bagaimana cara mengubah warna indikator progressBar di Android

178

Saya telah menetapkan Horizontal ProgressBar.

Saya ingin mengubah warna progres menjadi kuning.

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

Masalahnya, warna progresnya berbeda di perangkat yang berbeda. Jadi, saya ingin memperbaiki warna progres.

Nishant Shah
sumber
jawaban di atas mengubah seluruh warna latar belakang dan itu adalah ambigios yang mengubah ketinggian progress bar menjadi sangat maks. yang tidak dapat diubah dalam xml. cara yang lebih baik untuk mengubah status hanya progress bar bahwa berapa banyak yang diselesaikan adalah 20% warna merah, 50% warna kuning 70% dan di atas warna hijau. Anda dapat melakukannya secara terprogram di java. bagikan jawaban Anda jika Anda memiliki solusi lain.
Mubashar

Jawaban:

365

Saya menyalin ini dari salah satu aplikasi saya, jadi mungkin ada beberapa atribut tambahan, tetapi harus memberi Anda ide. Ini dari tata letak yang memiliki bilah progres:

<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" />

Kemudian buat drawable baru dengan sesuatu yang mirip dengan yang berikut ini (Dalam hal ini 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>

Anda dapat mengubah warna sesuai kebutuhan, ini akan memberi Anda bilah kemajuan hijau.

Ryan
sumber
Dan saya juga menghapus android ini: indeterminate = "false"
Nishant Shah
2
Tolong bantu aku. Saya mencoba membuat greenprogress.xml dengan menyalin kode Anda tetapi Android Studio 0.4.6 tandai <layer-list> sebagai dan kesalahan "Elemen-daftar harus dinyatakan" apa yang harus saya lakukan?
UmAnusorn
1
Apakah mungkin untuk mengubah warna secara dinamis?
async
dapatkah warna diubah tergantung pada nilai kemajuan saat ini yang ditentukan pada bilah aktual?
Jonathan
@Ryan Akan sangat membantu untuk menjelaskan apa android:id="@android:id/progress", android:id="@android:id/background"dan android:id="@android:id/secondaryProgress"berdiri untuk.
RustamG
103

Solusi yang lebih sederhana:

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>
Nitin Saxena
sumber
1
di sini @ color / disable adalah warna khusus
Nitin Saxena
2
Atau <solid android: color = "@ android: color / black" />, atau bahkan <solid android: color = "# ff33b5e5" />
superarts.org
2
Ini cukup android: indeterminateTint = "@ color / white" untuk tuas API 21 ke atas
Ghanshyam Nayma
53

Cukup buat gaya di values/styles.xml.

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

Kemudian atur gaya ini sebagai ProgressBartema Anda .

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

dan tidak masalah bilah kemajuan Anda bersifat horizontal atau bundar. Itu saja.

Ali Zeynali
sumber
1
Wow, solusi paling sederhana, bekerja untuk saya. Saya bertanya-tanya mengapa jawaban ini memiliki begitu banyak suara.
Pavel Shorokhov
38

Jika Anda hanya ingin mengubah warna bilah kemajuan, Anda cukup menggunakan filter warna dalam metode onCreate () aktivitas Anda:

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);

Ide dari sini .

Anda hanya perlu melakukan ini untuk versi pra-lolipop. Pada Lollipop Anda dapat menggunakan atribut style colorAccent.

amfcosta
sumber
Untuk SeekBaritu adalah sama, hanya menambahkan untuk API 16: seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);. Ini akan mengubah warna ibu jari bundar itu.
Sufian
1
Memanggil setColorFilter()drawable secara langsung akan menerapkan warna di mana-mana. Karena ini adalah apa yang saya tidak perlu, aku hanya disebut mutate()pada Drawable(yaitu sepertiseekBar.getThumb().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
Sufian
3
Saya telah melihat solusi ini di tempat lain tetapi semua yang dilakukannya (pengujian pada perangkat Gingerbread) adalah mengubah seluruh progress bar menjadi satu warna, sehingga tidak mungkin melihat kemajuan yang sebenarnya
Neil C. Obremski
@ NeilC.Obremski ya Anda benar. Mungkin spesifik ROM, atau mungkin versi spesifik. Saya harus menghapusnya sama sekali. Mudah-mudahan kita akan segera porting ini ke versi Android yang lebih lama (via lib dukungan).
Sufian
25

untuk API level 21 atau lebih tinggi gunakan saja

android:progressBackgroundTint="@color/yourBackgroundColor"
android:progressTint="@color/yourColor"
Mohammad Mousavi
sumber
6

Ada 3 cara untuk menyelesaikan pertanyaan ini:

  1. Cara menyesuaikan warna progressbar secara deklaratif
  2. Cara menyesuaikan warna progressbar secara terprogram, tetapi memilih warna dari berbagai warna yang telah ditentukan yang dinyatakan sebelum waktu kompilasi
  3. Cara menyesuaikan warna progressbar secara terprogram, dan juga membuat warna secara terprogram.

Secara khusus ada banyak kebingungan di sekitar # 2 dan # 3, seperti terlihat dalam komentar untuk jawaban amfcosta. Jawaban itu akan menghasilkan hasil warna yang tidak dapat diprediksi kapan saja Anda ingin mengatur progressbar ke apa pun kecuali warna primer, karena hanya memodifikasi warna latar belakang, dan area "clip" progress bar yang sebenarnya masih akan menjadi overlay kuning dengan opacity berkurang. Misalnya, menggunakan metode itu untuk mengatur latar belakang ke ungu gelap akan menghasilkan progress bar "klip" warna beberapa warna merah muda gila yang dihasilkan dari pencampuran ungu gelap dan kuning melalui alpha berkurang.

Jadi bagaimanapun, # 1 dijawab dengan sempurna oleh Ryan dan Štarke menjawab sebagian besar dari # 3, tetapi bagi mereka yang mencari solusi lengkap untuk # 2 dan # 3:


Cara menyesuaikan warna progressbar secara terprogram, tetapi pilih warna dari warna yang telah ditentukan yang dinyatakan dalam XML

res / drawable / my_progressbar.xml :

Buat file ini tetapi ubah warna dalam my_progress dan my_secondsProgress:

(CATATAN: Ini hanya salinan file XML aktual yang mendefinisikan SDK ProgressBar android default, tapi saya telah mengubah ID dan Warna. Dokumen aslinya bernama 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>

Di Jawa Anda :

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)

Cara menyesuaikan warna progressbar secara terprogram, dan juga membuat warna secara terprogram

EDIT: Saya menemukan waktu untuk menyelesaikan ini dengan benar. Jawaban saya sebelumnya meninggalkan ini agak ambigu.

ProgressBar terdiri dari 3 Drawables dalam sebuah LayerDrawable.

  1. Layer 1 adalah latar belakangnya
  2. Lapisan 2 adalah warna kemajuan sekunder
  3. Layer 3 adalah warna progress bar utama

Pada contoh di bawah ini saya akan mengubah warna progress bar utama menjadi cyan.

//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);

Contoh itu mengaturnya ke warna solid. Anda dapat mengaturnya ke warna gradien dengan mengganti

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

dengan

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

Bersulang.

-Tombak

tombak
sumber
apa itu viewUtils di viewUtils.convertDpToPixel (5);
Nikos Hidalgo
1
Hai @NikosHidalgo - Anda dapat melihat metode yang hampir identik di sini: stackoverflow.com/questions/12849366/… . Satu-satunya perbedaan adalah bahwa saya membangun ViewUtilsreferensi saya dengan Context, sehingga saya tidak perlu melewati Contextketika memanggilconvertDpToPixel()
lance.dolan
Terima kasih atas balasan secepatnya, terutama pada jawaban yang telah diposting sejak lama!
Nikos Hidalgo
Haha, aku benar-benar harus meregangkan otakku untuk mengingat: p
lance.dolan
4

Jika Anda berada di API level 21 atau lebih tinggi, Anda dapat menggunakan atribut XML ini:

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

Solusi paling sederhana yang saya temukan adalah sesuatu seperti ini:

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

Letakkan styles.xmlfile di atas dalam res > valuesfolder.

CATATAN: Jika Anda menggunakan warna aksen lain, maka solusi sebelumnya harus baik untuk digunakan.

API 21 atau LEBIH TINGGI

Sazid
sumber
Ini solusi terbaik. 100% terkait dengan pertanyaan yang diajukan. sangat sederhana
Pir Fahim Shah
3
final LayerDrawable layers = (LayerDrawable) progressBar.getProgressDrawable();
layers.getDrawable(2).setColorFilter(color,PorterDuff.Mode.SRC_IN);
pengguna3135773
sumber
1
Coba tambahkan sedikit penjelasan pada jawaban Anda. Kode hanya jawaban yang tidak disarankan.
Alexei
Saya ingin mendapatkan penjelasan di balik indeks 2 di getDrawable, tetapi setidaknya ini adalah satu-satunya solusi yang bekerja untuk saya, jadi terima kasih!
Nikos Hidalgo
2

Bagi siapa pun yang mencari cara melakukannya secara terprogram:

    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);

Mengatur id ke drawable sangat penting, dan menjaga batas dan status progress bar yang sebenarnya

Štarke
sumber
1

Kalian benar-benar membuatku sakit kepala. Apa yang dapat Anda lakukan adalah membuat daftar lapisan Anda dapat ditarik melalui xml terlebih dahulu (artinya latar belakang sebagai lapisan pertama, gambar yang mewakili kemajuan sekunder sebagai lapisan kedua, dan gambar lain yang dapat menggambarkan kemajuan utama sebagai lapisan terakhir), lalu ubah warna pada kode dengan melakukan hal berikut:

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);
    }
}

Metode ini akan memberikan Anda fleksibilitas terbaik untuk memiliki pengukuran drawable asli Anda dinyatakan pada xml, TANPA MODIFIKASI PADA STRUKTUR PERUSAHAAN SETELAH, terutama jika Anda perlu memiliki folder layar file file xml spesifik, maka hanya memodifikasi HANYA WARNA YANG HANYA melalui kode. Tidak ada instantiating ShapeDrawable baru dari awal apa pun.

Pier Betos
sumber
1

Warna ProgressBar dapat diubah sebagai berikut:

/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);
}
Milan Hlinák
sumber
1

Buat sumber daya yang bisa digambar latar belakang apa yang Anda butuhkan, dalam kasus saya saya menamainya bg_custom_progressbar.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>

Kemudian gunakan seperti latar belakang kustom ini

 <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" />

Ini berfungsi baik untuk saya

Md Juyel Rana
sumber
0

Dalam 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
    }
Soumen Das
sumber
0

Dengan Perpustakaan Komponen Bahan Anda dapat menggunakan ProgressIndicatordengan app:indicatorColoratribut untuk mengubah warna:

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

masukkan deskripsi gambar di sini

Catatan : setidaknya memerlukan versi 1.3.0-alpha01.

Dengan ProgressBarAnda dapat mengganti warna menggunakan:

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

dengan:

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

masukkan deskripsi gambar di sini

Gabriele Mariotti
sumber
0

Jika Anda ingin mengatur warna progres primer dan sekunder ke progress progress bar secara terprogram di android maka gunakan cuplikan di bawah ini

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));
Rahul Kamble
sumber