Cara mengubah warna progres bilah kemajuan di Android

473

Saya menggunakan bilah kemajuan horizontal di aplikasi Android saya, dan saya ingin mengubah warna progresnya (yang secara default adalah Kuning). Bagaimana saya bisa menggunakan code(bukan XML)?

WhiteTigerK
sumber
Sudahkah Anda mencoba MyProgressBar.setProgressDrawable (Drawable d) menentukan bitmap dengan warna yang Anda inginkan? developer.android.com/reference/android/widget/… developer.android.com/reference/android/graphics/drawable/…
fupsduck
2
Ya saya sudah mencobanya tetapi tidak berhasil. Ini menetapkan warna latar belakang dari seluruh tampilan progress bar alih-alih mengatur warna latar belakang hanya bilah itu sendiri. Terima kasih.
WhiteTigerK
21
android:indeterminateTint="@android:color/white"hanya bekerja di API> = 21
Madeyedexter

Jawaban:

291

Maaf, ini bukan jawabannya, tapi apa yang mendorong persyaratan menetapkannya dari kode? Dan .setProgressDrawableharus bekerja jika sudah didefinisikan dengan benar

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@android:id/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="@android:id/secondaryProgress">
    <clip>
        <shape>
            <corners android:radius="5dip" />
            <gradient
                    android:startColor="#80ffd300"
                    android:centerColor="#80ffb600"
                    android:centerY="0.75"
                    android:endColor="#a0ffcb00"
                    android:angle="270"
            />
        </shape>
    </clip>
</item>

<item android:id="@android:id/progress">
    <clip>
        <shape>
            <corners
                android:radius="5dip" />
            <gradient
                android:startColor="@color/progress_start"
                android:endColor="@color/progress_end"
                android:angle="270" 
            />
        </shape>
    </clip>
</item>

</layer-list>
Alex Volovoy
sumber
4
Alasannya adalah karena saya membuat bilah progres secara dinamis, dan mengatur warnanya atas permintaan pengguna. Karena saya biasanya menggunakan kode untuk membuat layar dan komponen GUI saya, saya tidak terbiasa dengan XML yang terlampir dan saya tidak tahu apa itu daftar-lapisan (walaupun saya menduga Anda sedang membangun progress bar berdasarkan beberapa lapisan) ..) Jika saya ingin menggunakan XML yang Anda lampirkan - di mana saya harus meletakkannya di folder proyek dan apakah ada hal lain yang perlu saya lakukan untuk membuat bilah kemajuan berdasarkan pada pengaturan XML? Terima kasih.
WhiteTigerK
1
Anda menyimpan xml ini sebagai file dan menaruhnya di folder drawable (misalkan my_progress.xml) daripada yang Anda tetapkan sebagai drawable di MyProgressBar.setProgressDrawable () Untuk mengubah warna - Anda harus mengubah nilai-nilai itu di @ color / progress_start @ color / progress_end Pada dasarnya ini adalah gradien dan Anda dapat menempatkan hex di sana.
Alex Volovoy
3
Catatan - file adalah salinan dari yang ada di SDK. Saya telah menjatuhkan hak cipta di sini. Jika Anda melihat di folder res / drawable Anda akan melihat persis apa yang telah saya posting - warna diatur ke gradien kuning, bukan warna kustom.
Alex Volovoy
7
Itu tidak menunjukkan perubahan warna kepada saya. tolong beri tahu warna yang berhasil.
Praveen
Hai Alex, jawaban Anda sangat bagus. tapi, saya mencoba mengubah warna roda progres kustom saat runtime. tapi saya tidak bisa. tolong bantu saya untuk menyelesaikan masalah saya .. setelah kemajuan mencapai 100%, maka waktu itu ubah warna dan mulai kemajuan .. saya unduh kode dari ini .. stackoverflow.com/questions/18503718/…
harikrishnan
485

Untuk ProgressBar horizontal, Anda dapat menggunakan ColorFilterjuga, seperti ini:

progressBar.getProgressDrawable().setColorFilter(
    Color.RED, android.graphics.PorterDuff.Mode.SRC_IN);

ProgressBar Merah menggunakan filter warna

Catatan: Ini mengubah tampilan semua bilah progres di aplikasi Anda. Untuk hanya mengubah satu bilah progres spesifik, lakukan ini:

Drawable progressDrawable = progressBar.getProgressDrawable().mutate();
progressDrawable.setColorFilter(Color.RED, android.graphics.PorterDuff.Mode.SRC_IN);
progressBar.setProgressDrawable(progressDrawable);

Jika progressBar tidak tentu maka gunakan getIndeterminateDrawable()sebagai gantinya getProgressDrawable().

Karena Lollipop (API 21) Anda dapat mengatur warna progres:

progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));

ProgressBar Merah menggunakan warna progres

Torben Kohlmeier
sumber
7
Saya ingin menggunakan jawaban ini karena bagi saya sepertinya jawaban yang paling sederhana, tetapi bilah kemajuan saya sepenuhnya merah terlepas dari nilai kemajuan. Anda yakin dengan Mode yang digunakan?
LG
33
@resus Saya memiliki masalah yang sama, bilah sepenuhnya merah dan tidak ada kemajuan yang terlihat. Tapi saya menyelesaikannya dengan mengubah Mode.SRC_IN ke Mode.MULTIPLY.
Derzu
40
Jangan lupa untuk melakukan hal yang sama karena getIndeterminateDrawablejika Anda menggunakan progres tidak pasti.
Thommy
6
Maklum, 'Mode' dalam konteks ini merujuk ke android.graphics.PorterDuff.Mode
1owk3y
9
bagaimana cara tidak mengubah warna latar belakang? Saya hanya ingin mengubah warna progres.
Kangear
364

Ini tidak terprogram tetapi saya pikir itu bisa membantu banyak orang.
Saya banyak mencoba dan cara paling efisien adalah menambahkan baris ini ke ProgressBar saya di File .xml:

            android:indeterminate="true"
            android:indeterminateTintMode="src_atop"
            android:indeterminateTint="@color/secondary"

Jadi pada akhirnya kode ini melakukannya untuk saya:

<ProgressBar
            android:id="@+id/progressBar"
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:layout_marginTop="50dp"
            android:layout_marginBottom="50dp"
            android:visibility="visible"
            android:indeterminate="true"
            android:indeterminateTintMode="src_atop"
            android:indeterminateTint="@color/secondary">

Solusi ini berfungsi untuk API 21+

FFirmenich
sumber
45
Membutuhkan API level minimum 21
Apfelsaft
Ada juga metode penyetel untuk properti ini yang dapat dipanggil jika warna dinamis harus ditetapkan.
ras
Apakah saya harus membuat file sumber daya khusus untuk api 21+ dan api <= 20? Atau apakah atribut-atribut itu hanya diabaikan dalam api <= 20?
prom85
1
@shriduttkothari bagaimana mungkin ini yang terbaik? ... dari
21+
2
Jawaban terbaik karena Android bergeser dari minimum 4.x
Tom
229

Untuk progressbar (pemintal) tak tentu saya, saya hanya mengatur filter warna pada drawable. Berfungsi bagus dan hanya satu baris.

Contoh di mana pengaturan warna menjadi merah:

ProgressBar spinner = new android.widget.ProgressBar(
                context,
                null,
                android.R.attr.progressBarStyle);

spinner.getIndeterminateDrawable().setColorFilter(0xFFFF0000, android.graphics.PorterDuff.Mode.MULTIPLY);

masukkan deskripsi gambar di sini

jhewati
sumber
16
Saya suka jawaban Anda yang terbaik. Agar tambang berfungsi, saya harus melakukan ini: myProgressBarSpinner.getIndeterminateDrawable (). SetColorFilter (LightingColorFilter baru (0xFF000000, foregroundColorDesired));
Seni Geigel
4
Perhatikan juga bahwa melakukan ini akan mengubah drawable dari SEMUA progress bar di aplikasi Anda. Untuk melakukan ini hanya untuk yang tertentu, panggil mutate () pada drawable, lalu atur filter warna di atasnya dan kemudian panggil setIntederminateDrawable pada progressBar Anda.
dimsuz
3
NB: Mereka yang menggunakan ini dan bertanya-tanya mengapa warnanya tidak sama persis dengan string hex yang mereka masukkan, memiliki beberapa filter warna. Ubah android.graphics.PorterDuff.Mode.MULTIPLYke PorterDuff.Mode.SRC_INdan Anda akan mendapatkan warna hex yang tepat.
micnguyen
Saya pikir dia hanya perlu jawaban ini ..... android: indeterminateTint = "@ android: color / black"
Muhammad Adil
4
saya digunakan sebagai: progressBar = (ProgressBar) findViewById (R.id.progressBar); progressBar.getIndeterminateDrawable (). setColorFilter (ContextCompat.getColor (ini, android.R.color.white), android.graphics.PorterDuff.Mode.MULTIPLY);
ashishdhiman2007
188

Ini adalah pertanyaan lama, tetapi menggunakan tema tidak disebutkan di sini. Jika tema default Anda gunakan AppCompat, ProgressBarwarna colorAccentAnda akan Anda tentukan.

Mengubah colorAccentjuga akan mengubah ProgressBarwarna Anda, tetapi ada perubahan juga mencerminkan di banyak tempat. Jadi, jika Anda menginginkan warna yang berbeda hanya untuk warna tertentu, PregressBarAnda dapat melakukannya dengan menerapkan tema itu ProgressBar:

  • Perpanjang tema default Anda dan timpa colorAccent

    <style name="AppTheme.WhiteAccent">
        <item name="colorAccent">@color/white</item> <!-- Whatever color you want-->
    </style>
  • Dan di ProgressBartambahkan android:themeatribut:

    android:theme="@style/AppTheme.WhiteAccent"

Jadi akan terlihat seperti ini:

<ProgressBar
        android:id="@+id/loading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:padding="10dp"
        android:theme="@style/AppTheme.WhiteAccent" />

Jadi Anda hanya mengubah a colorAccentuntuk Anda ProgressBar.

Catatan : Menggunakan styletidak akan berfungsi. Anda hanya perlu menggunakannya android:theme. Anda dapat menemukan lebih banyak penggunaan tema di sini: https://plus.google.com/u/0/+AndroidDevelopers/posts/JXHKyhsWHAH

kirtan403
sumber
18
akhirnya! terima kasih, sepertinya tidak banyak pengembang yang menggunakan AppCompat, banyak pengguna hanya memilih jawaban dengan solusi untuk API 21+, tidak baik sama sekali, mereka harus mendukung lebih banyak perangkat / OS sebanyak mungkin
pengguna25
1
Luar biasa! Bekerja untuk saya, tapi saya harus memastikan ada orang tua = "@ style / Theme.AppCompat" di suatu tempat hierarki gaya saya punya orangtua lain dan itu tidak berhasil pada awalnya.
Nublodeveloper
@Nublodeveloper Ya saya sebutkan di baris pertama jika Anda perhatikan.
kirtan403
1
@ kirtan403 Ah, ya, saya mengerti sekarang Anda menyebutkannya, tapi saya tidak mengerti seperti itu ketika saya pertama kali membacanya. Saya membacanya terlalu cepat dan saya sedang mencari kode. Bagaimanapun, terima kasih, jawaban Anda adalah yang terbaik untuk saya!
Nublodeveloper
+1 Menyukai solusi Anda. Tapi bagaimana cara mengatur warna tema di java ??? Sebagai contoh jika saya ingin menjadi merah <font color = "red"> # ff5900 </color>
Maseed
54

Semua API

jika menggunakan semua API, buat saja tema dengan gaya

style.xml

<resources>

    //...

    <style name="progressBarBlue" parent="@style/Theme.AppCompat">
        <item name="colorAccent">@color/blue</item>
    </style>

</resources>

dan digunakan dalam proses

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

API level 21 dan lebih tinggi

jika digunakan di API level 21 dan lebih tinggi cukup gunakan kode ini:

<ProgressBar
   //...
   android:indeterminate="true"
   android:indeterminateTintMode="src_atop"
   android:indeterminateTint="@color/secondary"/>
Rasoul Miri
sumber
1
Bagus, saya pikir metode style.xml adalah yang terbaik. (Tidak perlu di atas 20 api)
iamkdblue
1
Solusi terbaik jika Anda menginginkan satu solusi untuk semua API Terima kasih :)
Naveen
34

sesuai beberapa saran, Anda BISA menentukan bentuk dan clipdrawable dengan warna, lalu mengaturnya. Saya memiliki ini berfungsi secara terprogram. Ini adalah bagaimana saya melakukannya ..

Pertama, pastikan Anda mengimpor perpustakaan yang dapat digambar ..

import android.graphics.drawable.*;

Kemudian gunakan kode yang mirip dengan di bawah ini;

ProgressBar pg = (ProgressBar)row.findViewById(R.id.progress);
final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 };
pgDrawable = new ShapeDrawable(new RoundRectShape(roundedCorners, null,null));
String MyColor = "#FF00FF";
pgDrawable.getPaint().setColor(Color.parseColor(MyColor));
ClipDrawable progress = new ClipDrawable(pgDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL);
pg.setProgressDrawable(progress);   
pg.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.progress_horizontal));
pg.setProgress(45);
PaulieG
sumber
1
Saya mencoba kode di atas, sayangnya hanya menghasilkan progress bar "kosong". Apakah saya melewatkan sesuatu?
OceanBlue
Anda perlu memanggil setLevel di ClipDrawable. Dibutuhkan nilai dari 0 hingga 10.000. Jadi, progress.setLevel (2500) akan menjadi 25% penuh.
HappyEngineer
1
Saya telah mengirimkan hasil edit ke jawaban yang menjelaskan satu alasan untuk bilah kemajuan "kosong" - dan 2 cara untuk memperbaikinya (termasuk perbaikan @ HappyEngineer)
Richard Le Mesurier
@RichardLeMesurier dapatkah Anda memposting penjelasan + 2 cara di bagian komentar? progress.setLevel(2500)tidak berfungsi untuk saya dan ternyata hasil edit Anda tidak diterima karena alasan tertentu. Terima kasih. +1.
ateiob
@ateiob Saya telah menulis jawaban baru untuk menjelaskan ...
Richard Le Mesurier
32

Ini bekerja untuk saya:

<ProgressBar
 android:indeterminateTint="#d60909"
 ... />
MOH3N
sumber
12
Hanya digunakan di API level 21 dan lebih tinggi
Numair
28

jika tak tentu:

((ProgressBar)findViewById(R.id.progressBar))
    .getIndeterminateDrawable()
    .setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
pisau
sumber
Saya menggunakan ini, tetapi itu tidak bernyawa, hanya warna telah diterapkan ... Saya menggunakan progressbar melingkar
Manikandan
24

Ini bekerja untuk saya. Ini juga berfungsi untuk versi yang lebih rendah. Tambahkan ini ke syles.xml Anda

<style name="ProgressBarTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorAccent">@color/colorPrimary</item>
</style>

Dan gunakan seperti ini di xml

<ProgressBar
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:theme="@style/ProgressBarTheme"
   />
Devinder Jhinjer
sumber
Saya sudah menerapkan ini di aplikasi sampel CryptoTweets . Saya menemukan bahwa tema induk tidak diperlukan agar solusi ini berfungsi seperti yang diharapkan. parent="ThemeOverlay.AppCompat.Light"
Adam Hurwitz
23

Saat ini di 2016 saya menemukan beberapa perangkat pra-Lollipop tidak menghormati colorAccentpengaturan, jadi solusi terakhir saya untuk semua API adalah sebagai berikut:

// fixes pre-Lollipop progressBar indeterminateDrawable tinting
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {

    Drawable wrapDrawable = DrawableCompat.wrap(mProgressBar.getIndeterminateDrawable());
    DrawableCompat.setTint(wrapDrawable, ContextCompat.getColor(getContext(), android.R.color.holo_green_light));
    mProgressBar.setIndeterminateDrawable(DrawableCompat.unwrap(wrapDrawable));
} else {
    mProgressBar.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(getContext(), android.R.color.holo_green_light), PorterDuff.Mode.SRC_IN);
}

Untuk poin bonus, itu tidak menggunakan kode usang. Cobalah!

Henrique de Sousa
sumber
Jangan lupa menelepon wrapDrawable.mutate()denganDrawableCompat.setTint(wrapDrawable.mutate(), ContextCompat.getColor(getContext(), android.R.color.holo_green_light));
Tarsem Singh
Tidak bekerja di Android KitKat 4.4.2.
pradip tilala
Hanya mencobanya (lagi) pada emulator 4.4.2 baru yang baru dan bekerja tanpa masalah apa pun, periksa .xmlpengaturan Anda dan juga jika ada sesuatu yang menimpa ProgressBarwarnanya.
Henrique de Sousa
20

Inilah yang saya lakukan. Bekerja.

ProgressBar:

<ProgressBar
            android:id="@+id/progressBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="4"
            android:indeterminateDrawable="@drawable/progressdrawable"
           />

progressdrawable.xml:
Di sini gunakan gradient untuk mengubah warna sesuka Anda. Dan android: toDegrees = "X" meningkatkan nilai X dan progressbar memutar dengan cepat. Kurangi dan putar lambat. Sesuaikan sesuai dengan kebutuhan Anda.

<?xml version="1.0" encoding="utf-8"?>
     <rotate xmlns:android="http://schemas.android.com/apk/res/android"
            android:duration="4000"
            android:fromDegrees="0"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="360" >

            <shape
                android:innerRadius="20dp"
                android:shape="ring"
                android:thickness="4dp"
                android:useLevel="false" >
                <size
                    android:height="48dp"
                    android:width="48dp" />

                <gradient
                    android:centerColor="#80ec7e2a"
                    android:centerY="0.5"
                    android:endColor="#ffec7e2a"
                    android:startColor="#00ec7e2a"
                    android:type="sweep"
                    android:useLevel="false" />
            </shape>

        </rotate>

Sampel: masukkan deskripsi gambar di sini

Debasish Ghosh
sumber
Ini menunjukkan animasi yang sama sekali berbeda (berpenampilan buruk) dari pada animasi standar.
Ixx
18

Memukul masalah yang sama saat mengerjakan memodifikasi tampilan / nuansa bilah kemajuan default. Berikut ini beberapa info lagi yang diharapkan akan membantu orang :)

  • Nama file xml hanya boleh mengandung karakter: a-z0-9_.(mis. Tanpa huruf kapital!)
  • Untuk referensi "drawable" Anda itu R.drawable.filename
  • Untuk mengganti tampilan default, Anda menggunakan myProgressBar.setProgressDrawable(...), namun Anda tidak bisa hanya merujuk ke tata letak kustom R.drawable.filenameAnda, Anda harus mengambilnya sebagai Drawable:
    Resources res = getResources();
    myProgressBar.setProgressDrawable(res.getDrawable(R.drawable.filename);
  • Anda perlu mengatur gaya sebelum mengatur kemajuan / kemajuan sekunder / maks (pengaturan sesudahnya untuk saya menghasilkan bilah kemajuan 'kosong')
pyko
sumber
15

Mungkin ada satu hal yang belum dirujuk dalam jawaban ini:

Jika tema Anda merupakan turunan dari Theme.AppCompat, ProgressBarakan menganggap warna yang Anda tetapkan "colorAccent"dalam tema Anda.

Jadi, menggunakan ..

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

..akan mewarnai warna ProgressBar secara otomatis ke @color/custom_color.

Henrique de Sousa
sumber
1
Saya perlu menggunakan <item name = "android: colorAccent"> @ color / highlight </item>
tonisives
15
android:progressTint="#ffffff" 
Paul
sumber
15

Anda dapat mencoba mengubah Gaya, Tema, atau menggunakan Android: indeterminateTint = "@ color / yourColor" di mana pun Anda inginkan, tetapi hanya ada satu cara yang dapat dilakukan untuk bekerja pada versi Android SKD:

Jika bilah kemajuan Anda tidak pasti, silakan gunakan:

progressBar.getProgressDrawable().setColorFilter(ContextCompat.getColor(context, R.color.yourColor), PorterDuff.Mode.SRC_IN );

Jika bilah kemajuan Anda tidak pasti, silakan gunakan:

progressBar.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(getContext(), R.color.yourColor), PorterDuff.Mode.SRC_IN );

Sangat menyedihkan bahwa Android berantakan!

Adriano Moutinho
sumber
Terima kasih! Ini bekerja untuk tak tentu ProgressBar, tetapi untuk menentukan itu melukis seluruh skala dengan warna.
CoolMind
14

Bagaimana saya melakukannya di ProgressBar horizontal:

    LayerDrawable layerDrawable = (LayerDrawable) progressBar.getProgressDrawable();
    Drawable progressDrawable = layerDrawable.findDrawableByLayerId(android.R.id.progress);
    progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
mieszk3
sumber
2
Saya melakukan hal yang sama, ditambah perubahan warna latar belakang: layerDrawable.findDrawableByLayerId (android.R.id.background) .setColorFilter (trackColor, PorterDuff.Mode.SRC);
Kamen Dobrev
1
Jawaban ini bersama dengan komentar @KamenDobrev adalah satu-satunya yang benar-benar melakukan apa yang saya inginkan. Ketika saya hanya mengatur filter warna untuk kemajuan, warna latar belakang juga berubah.
m_katsifarakis
13

Solusi paling sederhana jika Anda ingin mengubah warna dalam file layout xml, gunakan kode di bawah ini dan gunakan properti indeterminateTint untuk warna yang Anda inginkan.

    <ProgressBar
      android:id="@+id/progressBar"
      style="?android:attr/progressBarStyle"
      android:layout_width="wrap_content"
      android:indeterminate="true"
      android:indeterminateTintMode="src_atop"
      android:indeterminateTint="#ddbd4e"
      android:layout_height="wrap_content"
      android:layout_marginBottom="20dp"
      android:layout_alignParentBottom="true"
      android:layout_centerHorizontal="true" />
Naveed Ahmad
sumber
12

Solusi ini bekerja untuk saya:

<style name="Progressbar.White" parent="AppTheme">
    <item name="colorControlActivated">@color/white</item>
</style>

<ProgressBar
    android:layout_width="@dimen/d_40"
    android:layout_height="@dimen/d_40"
    android:indeterminate="true"
    android:theme="@style/Progressbar.White"/>
S.Javed
sumber
8

Satu lagi hal kecil, solusi tema tidak berfungsi jika Anda mewarisi tema dasar, jadi untuk aplikasi yang ringkas tema Anda seharusnya:

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

Dan kemudian mengatur ini di tema progress bar

<ProgressBar
    android:id="@+id/progressCircle_progressBar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:theme="@style/AppTheme.Custom"
    android:indeterminate="true"/>
Calin
sumber
7

Untuk mengubah warna ProgressBar horizontal (dalam kotlin):

fun tintHorizontalProgress(progress: ProgressBar, @ColorInt color: Int = ContextCompat.getColor(progress.context, R.color.colorPrimary)){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        progress.progressTintList = ColorStateList.valueOf(color)
    } else{
        val layerDrawable = progress.progressDrawable as? LayerDrawable
        val progressDrawable = layerDrawable?.findDrawableByLayerId(android.R.id.progress)
        progressDrawable?.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
    }
}

Untuk mengubah warna ProgressBar yang tidak ditentukan:

fun tintIndeterminateProgress(progress: ProgressBar, @ColorInt color: Int = ContextCompat.getColor(progress.context, R.color.colorPrimary)){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        progress.indeterminateTintList = ColorStateList.valueOf(color)
    } else {
        (progress.indeterminateDrawable as? LayerDrawable)?.apply {
            if (numberOfLayers >= 2) {
                setId(0, android.R.id.progress)
                setId(1, android.R.id.secondaryProgress)
                val progressDrawable = findDrawableByLayerId(android.R.id.progress).mutate()
                progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
            }
        }
    }
}

Dan akhirnya biasanya mewarnai progressBars pra-lollipop

kemajuan yang diwarnai pada api 19

John
sumber
6

Gaya progress bar kustom horisontal:

Untuk mengubah warna latar belakang dan kemajuan bilah kemajuan horizontal.

<style name="MyProgressBar" parent="@style/Widget.AppCompat.ProgressBar.Horizontal">
    <item name="android:progressBackgroundTint">#69f0ae</item>
    <item name="android:progressTint">#b71c1c</item>
    <item name="android:minWidth">200dp</item>
</style>

Menerapkannya pada progress bar dengan mengatur atribut style, untuk style material kustom dan custom progress bar, periksa http://www.zoftino.com/android-progressbar-and-custom-progressbar-examples

Arnav Rao
sumber
3
ini membutuhkan api level minimum 21
Shihab Uddin
6

Diposting untuk menambahkan info tentang jawaban PaulieG, karena ateiob meminta saya untuk menjelaskan sesuatu ...


Saya dapat mengatakan bahwa ada (atau paling tidak, pada saat penulisan ketika saya melihat versi kode sumber Android saat ini) bug / masalah / optimasi dalam ProgressBarkode yang mengabaikan upaya untuk mengatur kemajuan ke nilai itu sudah di.

  • yaitu jika progres = 45, dan Anda mencoba mengaturnya ke 45, kode tidak akan melakukan apa-apa, dan tidak akan menggambar ulang progresnya .

Setelah menelepon ProgressBar.setProgressDrawable() , bilah kemajuan Anda akan kosong (karena Anda mengubah bagian yang dapat digambar).

Ini berarti Anda perlu mengatur kemajuan, dan menggambarnya kembali. Tetapi jika Anda hanya mengatur kemajuan ke nilai yang dipertahankan, itu tidak akan melakukan apa-apa.

Anda harus mengaturnya ke 0 terlebih dahulu, kemudian ke nilai "lama" lagi, dan bilah akan menggambar ulang.


Jadi untuk meringkas:

  • pertahankan nilai kemajuan "lama"
  • perbarui drawable / color (buat bilah kosong)
  • atur ulang kemajuan ke 0 (jika tidak, baris berikutnya tidak melakukan apa-apa)
  • setel ulang kemajuan ke nilai "lama" (bilah perbaikan)
  • batal

Di bawah ini adalah metode yang saya miliki yang melakukan ini:

protected void onResume()
{
    super.onResume();
    progBar = (ProgressBar) findViewById(R.id.progress_base);

    int oldProgress = progBar.getProgress();

    // define new drawable/colour
    final float[] roundedCorners = new float[]
        { 5, 5, 5, 5, 5, 5, 5, 5 };
    ShapeDrawable shape = new ShapeDrawable(new RoundRectShape(
        roundedCorners, null, null));
    String MyColor = "#FF00FF";
    shape.getPaint().setColor(Color.parseColor(MyColor));
    ClipDrawable clip = new ClipDrawable(shape, Gravity.LEFT,
        ClipDrawable.HORIZONTAL);
    progBar.setProgressDrawable(clip);

    progBar.setBackgroundDrawable(getResources().getDrawable(
        android.R.drawable.progress_horizontal));

    // work around: setProgress() ignores a change to the same value
    progBar.setProgress(0);
    progBar.setProgress(oldProgress);

    progBar.invalidate();
}

Sejauh solusi HappyEngineer, saya pikir itu solusi yang sama, untuk secara manual mengatur "kemajuan" offset. Dalam kedua kasus itu, kode di atas akan bekerja untuk Anda.

Richard Le Mesurier
sumber
Terima kasih .. ini benar-benar berfungsi .. tetapi drawable saya statis (dari sumber daya) .. tidak berfungsi. Ini hanya berfungsi setelah saya menambahkan "drawable.invalidateSelf ();" sebelum 'setProgress (0)' dan 'setProgressDrawable (drawable)'
Alécio Carvalho
5

Gunakan android.support.v4.graphics.drawable.DrawableCompat :

            Drawable progressDrawable = progressBar.getIndeterminateDrawable();
            if (progressDrawable  != null) {
                Drawable mutateDrawable = progressDrawable.mutate();
                DrawableCompat.setTint(mutateDrawable, primaryColor);
                progressBar.setProgressDrawable(mutateDrawable);
            }
Alécio Carvalho
sumber
5

cukup gunakan:

PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
    mode = PorterDuff.Mode.MULTIPLY;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
    progressBar.setProgressBackgroundTintList(ColorStateList.valueOf(Color.RED));
} else {
    Drawable progressDrawable;
    progressDrawable = (progressBar.isIndeterminate() ? progressBar.getIndeterminateDrawable() : progressBar.getProgressDrawable()).mutate();
    progressDrawable.setColorFilter(context.getResources().getColor(Color.RED), mode);
    progressBar.setProgressDrawable(progressDrawable);
}
Mohammad Fneish
sumber
4

Untuk ProgressBar gaya horizontal saya gunakan:

import android.widget.ProgressBar;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.ClipDrawable;
import android.view.Gravity;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;

public void setColours(ProgressBar progressBar,
                        int bgCol1, int bgCol2, 
                        int fg1Col1, int fg1Col2, int value1,
                        int fg2Col1, int fg2Col2, int value2)
  {
    //If solid colours are required for an element, then set
    //that elements Col1 param s the same as its Col2 param
    //(eg fg1Col1 == fg1Col2).

    //fgGradDirection and/or bgGradDirection could be parameters
    //if you require other gradient directions eg LEFT_RIGHT.

    GradientDrawable.Orientation fgGradDirection
        = GradientDrawable.Orientation.TOP_BOTTOM;
    GradientDrawable.Orientation bgGradDirection
        = GradientDrawable.Orientation.TOP_BOTTOM;

    //Background
    GradientDrawable bgGradDrawable = new GradientDrawable(
            bgGradDirection, new int[]{bgCol1, bgCol2});
    bgGradDrawable.setShape(GradientDrawable.RECTANGLE);
    bgGradDrawable.setCornerRadius(5);
    ClipDrawable bgclip = new ClipDrawable(
            bgGradDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL);     
    bgclip.setLevel(10000);

    //SecondaryProgress
    GradientDrawable fg2GradDrawable = new GradientDrawable(
            fgGradDirection, new int[]{fg2Col1, fg2Col2});
    fg2GradDrawable.setShape(GradientDrawable.RECTANGLE);
    fg2GradDrawable.setCornerRadius(5);
    ClipDrawable fg2clip = new ClipDrawable(
            fg2GradDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL);        

    //Progress
    GradientDrawable fg1GradDrawable = new GradientDrawable(
            fgGradDirection, new int[]{fg1Col1, fg1Col2});
    fg1GradDrawable.setShape(GradientDrawable.RECTANGLE);
    fg1GradDrawable.setCornerRadius(5);
    ClipDrawable fg1clip = new ClipDrawable(
            fg1GradDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL);        

    //Setup LayerDrawable and assign to progressBar
    Drawable[] progressDrawables = {bgclip, fg2clip, fg1clip};
    LayerDrawable progressLayerDrawable = new LayerDrawable(progressDrawables);     
    progressLayerDrawable.setId(0, android.R.id.background);
    progressLayerDrawable.setId(1, android.R.id.secondaryProgress);
    progressLayerDrawable.setId(2, android.R.id.progress);

    //Copy the existing ProgressDrawable bounds to the new one.
    Rect bounds = progressBar.getProgressDrawable().getBounds();
    progressBar.setProgressDrawable(progressLayerDrawable);     
    progressBar.getProgressDrawable().setBounds(bounds);

    // setProgress() ignores a change to the same value, so:
    if (value1 == 0)
        progressBar.setProgress(1);
    else
        progressBar.setProgress(0);
    progressBar.setProgress(value1);

    // setSecondaryProgress() ignores a change to the same value, so:
    if (value2 == 0)
        progressBar.setSecondaryProgress(1);
    else
        progressBar.setSecondaryProgress(0);
    progressBar.setSecondaryProgress(value2);

    //now force a redraw
    progressBar.invalidate();
  }

Contohnya adalah:

  setColours(myProgressBar, 
          0xff303030,   //bgCol1  grey 
          0xff909090,   //bgCol2  lighter grey 
          0xff0000FF,   //fg1Col1 blue 
          0xffFFFFFF,   //fg1Col2 white
          50,           //value1
          0xffFF0000,   //fg2Col1 red 
          0xffFFFFFF,   //fg2Col2 white
          75);          //value2

Jika Anda tidak membutuhkan 'kemajuan sekunder', cukup setel value2 ke value1.

Keith
sumber
4

Terapkan gaya khusus ini ke bilah kemajuan.

<style name="customProgress" parent="@android:style/Widget.ProgressBar.Small">
        <item name="android:indeterminateDrawable">@drawable/progress</item>
        <item name="android:duration">40</item>
        <item name="android:animationCache">true</item>
        <item name="android:drawingCacheQuality">low</item>
        <item name="android:persistentDrawingCache">animation</item>
    </style>

@ drawable / progress.xml -

<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/spinner_white"
    android:pivotX="50%"
    android:pivotY="50%" />

Gunakan jenis gambar ini untuk bilah kemajuan. masukkan deskripsi gambar di sini

Untuk hasil yang lebih baik, Anda dapat menggunakan beberapa gambar progres. Dan jangan ragu menggunakan gambar, karena Android Platform sendiri menggunakan gambar untuk progressbar. Kode diekstrak dari SDK :)

Neo
sumber
4

Sesuai muhammad-adil disarankan untuk SDK ver 21 ke atas

android:indeterminateTint="@color/orange"

dalam XML Bekerja untuk saya, cukup mudah.

mughil
sumber
Jika Anda ingin mengubah seluruh aplikasi, silakan ubah nilai <color name = "RedAccent"> # FE6C27 </color>. di Nilai Anda / colors.xml.
mughil
4

Berikut adalah kode untuk mengubah warna ProgressBar secara terprogram.

ProgressBar progressBar = (ProgressBar) findViewById(R.id.pb_listProgressBar);
int colorCodeDark = Color.parseColor("#F44336");
progressBar.setIndeterminateTintList(ColorStateList.valueOf(colorCodeDark));
Naveen Kumar M
sumber
4
ProgressBar freeRamPb = findViewById(R.id.free_ram_progress_bar);

freeRamPb.getProgressDrawable().setColorFilter(
Color.BLUE, android.graphics.PorterDuff.Mode.SRC_IN);
Pengecualian Null Pointer
sumber
Luar biasa. Solusi cepat dan efektif. Terima kasih!
Tobias Reich