Cara menambahkan warna tombol secara terprogram

120

Di pustaka AppCompat yang baru, kita bisa mewarnai tombol dengan cara ini:

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/follow"
    android:id="@+id/button_follow"
    android:backgroundTint="@color/blue_100"
    />

Bagaimana cara menyetel warna tombol secara terprogram dalam kode saya? Saya pada dasarnya mencoba menerapkan pewarnaan bersyarat pada tombol berdasarkan beberapa masukan pengguna.

Stephane
sumber
Apakah Anda yakin android: backgroundTint berfungsi di Pre-Lollipop? Saya menguji dengan Button dan ApCompatButton tetapi backgroundTint sepertinya hanya berfungsi di Lollipop.
Sharj
1
Silakan periksa jawaban ini .
Amit Vaghela

Jawaban:

162

Menurut dokumentasi , metode terkait android:backgroundTintadalah setBackgroundTintList (daftar ColorStateList)

Memperbarui

Ikuti tautan ini untuk mengetahui cara membuat Sumber Daya Daftar Status Warna.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:color="#your_color_here" />
</selector>

lalu muat menggunakan

setBackgroundTintList(contextInstance.getResources().getColorStateList(R.color.your_xml_name));

di mana contextInstancemerupakan instance dari aContext


menggunakan AppCompart

btnTag.setSupportButtonTintList(ContextCompat.getColorStateList(Activity.this, R.color.colorPrimary));
Api dingin
sumber
yang bukan merupakan warna, melainkan ColorStateList. Bagaimana cara memanfaatkannya?
Stephane
4
Saya mengerti bagaimana melakukannya sekarang, terima kasih, tetapi mengapa Android tidak mengizinkan Anda menggunakan warna secara manual? Untuk setiap warna dari setiap tombol yang saya miliki, saya harus membuat xml untuk ColorStateList? Sepertinya sia-sia bagi saya
Stephane
2
setBackgroundTintList membutuhkan API 21 meskipun Anda memanggilnya di AppCompatButton.
Sharj
29
Pustaka dukungan AppCompat menawarkan penolong statis: ViewCompat.setBackgroundTintList(View, ColorStateList)yang bisa digunakan sepenuhnya kembali ke API 4. Tapi itu hanya bekerja untuk tampilan yang mengimplementasikan TintableBackgroundView, misalnya AppCompatButton(bukan yang biasa Button).
Jon Adams
1
Sekarang, menggunakan ViewCompat.setBackgroundTintList(View, ColorStateList), seperti yang disarankan @Jon Adams, menjadi lebih masuk akal karena View.setSupportButtonTintList dibatasi dengan RestrictToanotasi. Detail di sini: developer.android.com/reference/android/support/annotation/…
AlexKost
75

Anda bisa menggunakan

button.setBackgroundTintList(ColorStateList.valueOf(resources.getColor(R.id.blue_100)));

Tapi saya akan merekomendasikan Anda untuk menggunakan pustaka dukungan yang dapat digambar tinting yang baru saja dirilis kemarin:

Drawable drawable = ...;

// Wrap the drawable so that future tinting calls work
// on pre-v21 devices. Always use the returned drawable.
drawable = DrawableCompat.wrap(drawable);

// We can now set a tint
DrawableCompat.setTint(drawable, Color.RED);
// ...or a tint list
DrawableCompat.setTintList(drawable, myColorStateList);
// ...and a different tint mode
DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_OVER);

Anda dapat menemukan lebih banyak dalam entri blog ini (lihat bagian "Warna yang dapat digambar")

dimsuz
sumber
2
bisakah kamu memberikan kode lengkap untuk mengatur warna menggunakan metode ur?
M. Usman Khan
Jawaban Terbaik...!
Gokul Nath KP
60

Sepertinya pandangan memiliki mekanisme sendiri untuk manajemen warna, jadi lebih baik akan menempatkan daftar warna:

ViewCompat.setBackgroundTintList(
    editText, 
    ColorStateList.valueOf(errorColor));
tse
sumber
Jauh lebih baik menggunakannya dengan cara ini, sehingga Anda mendapatkan kompatibilitas mundur dari API 4!
xarlymg89
salah satu solusi terbaik.
Atif AbbAsi
21

Dalam memperluas jawaban dimsuz dengan benar dengan memberikan situasi kode nyata, lihat cuplikan kode berikut:

    Drawable buttonDrawable = button.getBackground();
    buttonDrawable = DrawableCompat.wrap(buttonDrawable);
    //the color is a direct color int and not a color resource
    DrawableCompat.setTint(buttonDrawable, Color.RED);
    button.setBackground(buttonDrawable);

Solusi ini untuk skenario di mana drawable digunakan sebagai latar belakang tombol. Ini berfungsi pada perangkat pra-Lollipop juga.

Shayne3000
sumber
@TruptiNasit Senang mendengarnya.
Shayne3000
Bekerja untuk saya. Terima kasih.
wesley franks
1
@weslank. Sama-sama. Senang mendengarnya berhasil.
Shayne3000
7

Sudahkah Anda mencoba sesuatu seperti ini?

button.setBackgroundTintList(getResources().getColorStateList(R.id.blue_100));

perhatikan bahwa getResources () hanya akan bekerja dalam sebuah aktivitas. Tapi bisa juga disebut dalam setiap konteks.

Chris K.
sumber
Anda dapat membuat xml seperti yang dijelaskan di sini: developer.android.com/reference/android/content/res/…
Chris K.
getColorStateList tampaknya tidak digunakan lagi.
Cloudsurfin
1
setBackgroundTintList tampaknya memerlukan API level 21
Nashe
1
tombol. setBackgroundTintList (ContextCompat.getColorStateList (konteks, R.color.blue)); bekerja untuk saya
jesto paul
6

berikut cara melakukannya di kotlin:

view.background.setTint(ContextCompat.getColor(context, textColor))
Amin Keshavarzian
sumber
terima kasih, itu bekerja dengan baik!
Stoica Mircea
5

Anda dapat menggunakan contoh DrawableCompat

public static Drawable setTint(Drawable drawable, int color) {
    final Drawable newDrawable = DrawableCompat.wrap(drawable);
    DrawableCompat.setTint(newDrawable, color);
    return newDrawable;
}
mac229
sumber
5

ini mudah ditangani di Tombol Material baru dari pustaka desain material, pertama-tama, tambahkan ketergantungan:

implementation 'com.google.android.material:material:1.1.0-alpha07'

lalu di XML Anda, gunakan ini untuk tombol Anda:

<com.google.android.material.button.MaterialButton
    android:id="@+id/accept"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/i_accept"
    android:textSize="18sp"
    app:backgroundTint="@color/grayBackground_500" />

dan saat Anda ingin mengubah warnanya, berikut kodenya di Kotlin, Ini tidak usang dan dapat digunakan sebelum Android 21:

accept.backgroundTintList = ColorStateList.valueOf(ResourcesCompat.getColor(resources, 
R.color.colorPrimary, theme))
Amin Keshavarzian
sumber
Apakah ada yang serupa untuk warna teks itu sendiri?
Pengembang android
maksud Anda teks sebagai tombol dan Anda ingin mengubah warna latar belakang?
Amin Keshavarzian
4

Cara saya berhasil membuat milik saya bekerja adalah dengan menggunakan CompoundButtonCompat.setButtonTintList(button, colour).

Menurut pemahaman saya, ini berfungsi terlepas dari versi android.

Matt Jenje
sumber
3

Saya memiliki masalah serupa. Saya ingin mewarnai latar belakang drawable yang kompleks untuk tampilan berdasarkan nilai color (int). Saya berhasil menggunakan kode:

ColorStateList csl = new ColorStateList(new int[][]{{}}, new int[]{color});
textView.setBackgroundTintList(csl);

Dimana warna adalah nilai int yang mewakili warna yang dibutuhkan. Ini mewakili ColorStateList xml sederhana:

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:color="color here"/>
</selector>

Semoga ini membantu.

Tunjukkan pekerjaan Anda
sumber
2
Minimum diperlukan API level 21
forsberg
baik Anda bisa menggunakanColorStateList.valueOf(ColorInt)
user924
2

Untuk ImageButton Anda dapat menggunakan:

favoriteImageButton.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint
Saurabh Singh
sumber
setColorFilter tidak ditentukan untuk Buttons
Jérémy
Ini, untuk ImageButton.
Saurabh Singh
Oh oke, saya tidak tahu tentang itu. Tapi OP meminta Button. Dapatkah Anda mengedit jawaban Anda dengan detail ini sehingga saya dapat menghapus suara negatif saya?
Jérémy
2

Jika Anda menggunakan Kotlindan Material Design, Anda dapat mengubah warna MaterialButtonseperti ini:

myButton.background.setTintList(ContextCompat.getColorStateList(context, R.color.myColor))

Anda dapat meningkatkannya lebih baik lagi dengan membuat fungsi ekstensi MaterialButtonuntuk membuat kode Anda lebih mudah dibaca dan pengkodean Anda sedikit lebih nyaman:

fun MaterialButton.changeColor(color: Int) {
    this.background.setTintList(ContextCompat.getColorStateList(context, color))
}

Kemudian, Anda dapat menggunakan fungsi Anda di mana saja seperti ini:

myButton.changeColor(R.color.myColor)
Azizjon Kholmatov
sumber
1

Selain jawaban Shayne3000 , Anda juga dapat menggunakan sumber warna (tidak hanya warna int). Versi Kotlin :

var indicatorViewDrawable = itemHolder.indicatorView.background
indicatorViewDrawable = DrawableCompat.wrap(indicatorViewDrawable)
val color = ResourcesCompat.getColor(context.resources, R.color.AppGreenColor, null) // get your color from resources
DrawableCompat.setTint(indicatorViewDrawable, color)
itemHolder.indicatorView.background = indicatorViewDrawable
pelukan dingin
sumber
0

Jawaban yang disarankan di sini tidak berfungsi dengan baik pada android 5.0 jika daftar status warna berbasis XML Anda merujuk pada atribut bertema .. Misalnya, saya memiliki daftar status warna xml seperti:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="?colorPrimary" android:state_enabled="true"/>
    <item android:alpha="0.12" android:color="?attr/colorOnSurface"/>
</selector>

Menggunakan ini sebagai backgroundTint saya dari xml berfungsi dengan baik di Android 5.0 dan yang lainnya. Namun jika saya mencoba mengatur ini dalam kode seperti ini:

(Jangan lakukan ini)

myButton.setSupportButtonTintList(ContextCompat.getColorStateList(myButton.getContext(), R.color.btn_tint_primary));

Sebenarnya tidak masalah jika saya meneruskan Aktivitas atau konteks tombol ke metode ContextCompat.getColorStateList (), tidak ada yang memberi saya daftar status warna yang sesuai sehubungan dengan tema tempat tombol berada. Ini karena penggunaan atribut tema dalam daftar status warna tidak didukung hingga api 23 dan ContextCompat tidak melakukan sesuatu yang khusus untuk mengatasinya. Sebagai gantinya, Anda harus menggunakan AppCompatResources.getColorStateList () yang melakukan resolusi atribut parsing / tema sumber dayanya sendiri pada perangkat <API 23.

Sebaliknya, Anda harus menggunakan ini:

myButton.setSupportBackgroundTintList(AppCompatResources.getColorStateList(myButton.getContext(), R.color.btn_tint_primary));

TLDR: gunakan AppCompatResources dan bukan -ContextCompat- jika Anda perlu menyelesaikan resource bertema di semua versi API android.

Untuk informasi lebih lanjut tentang topik tersebut, lihat artikel ini .

Matt Wolfe
sumber