Programlı olarak düğme tonu ekleme


120

Yeni AppCompat kitaplığında, düğmeyi şu şekilde renklendirebiliriz:

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

Kodumda programlı olarak düğmenin renk tonunu nasıl ayarlayabilirim? Temel olarak bazı kullanıcı girdilerine göre düğmenin koşullu renklendirmesini uygulamaya çalışıyorum.


Android: backgroundTint'in Lollipop Öncesi üzerinde çalıştığından emin misiniz? Hem Button hem de ApCompatButton ile test ediyorum ama backgroundTint sadece Lollipop üzerinde çalışıyor gibi görünüyor.
Sharj

1
Lütfen bu yanıtı kontrol edin .
Amit Vaghela

Yanıtlar:


162

Göre belgeleri ile ilgili bir yöntem android:backgroundTintolup setBackgroundTintList (ColorStateList listesi)

Güncelleme

Bir Renk Durumu Listesi Kaynağının nasıl oluşturulduğunu öğrenmek için bu bağlantıyı izleyin .

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

sonra onu kullanarak yükleyin

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

contextInstancebir örneği neredeContext


AppCompart kullanarak

btnTag.setSupportButtonTintList(ContextCompat.getColorStateList(Activity.this, R.color.colorPrimary));

bu bir renk değil, bir ColorStateList. Bundan nasıl yararlanılır?
Stephane

4
Şimdi nasıl yapacağımı anlıyorum, ama Android neden bir rengi manuel olarak kullanmanıza izin vermiyor? Sahip olduğum her düğmenin her rengi için ColorStateList için bir xml oluşturmam gerekecek mi? Bu bana bir israf gibi görünüyor
Stephane

2
setBackgroundTintList, AppCompatButton'da çağırsanız bile API 21'e ihtiyaç duyar.
Sharj

29
AppCompat destek kitaplığı, ViewCompat.setBackgroundTintList(View, ColorStateList)API 4'e kadar tüm yollarda kullanılabilen statik bir yardımcı sunar . Ancak yalnızca TintableBackgroundView, örneğin AppCompatButton(her zamanki yerine Button) uygulayan görünümler için çalışır .
Jon Adams

1
Şimdi, ViewCompat.setBackgroundTintList(View, ColorStateList)@ Jon Adams'ın önerdiği gibi kullanmak , View.setSupportButtonTintList RestrictToek açıklama ile kısıtlandığından daha da mantıklı . Ayrıntılar burada: developer.android.com/reference/android/support/annotation/…
AlexKost

75

Kullanabilirsin

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

Ancak, dün piyasaya sürülen bir destek kitaplığı çekilebilir renklendirme kullanmanızı tavsiye ederim:

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

Bu blog gönderisinde daha fazlasını bulabilirsiniz ("Çekilebilir renklendirme" bölümüne bakın)


2
yöntemini kullanarak renk tonunu ayarlamak için eksiksiz kod sağlayabilir misiniz?
M. Usman Khan

En iyi cevap...!
Gokul Nath KP

60

Görünüşe göre görünümlerin ton yönetimi için kendi mekaniği var, bu nedenle renk listesi daha iyi koyulacak:

ViewCompat.setBackgroundTintList(
    editText, 
    ColorStateList.valueOf(errorColor));

Bu şekilde kullanmak çok daha iyi, böylece API 4'ten geriye dönük uyumluluk elde edersiniz!
xarlymg89

en iyi çözümlerden biri.
Atif AbbAsi

21

Dimsuz'un cevabını gerçek bir kod durumu sağlayarak doğru şekilde genişletmek için aşağıdaki kod parçacığına bakın:

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

Bu çözüm, bir çekilebilir öğenin düğmenin arka planı olarak kullanıldığı senaryo içindir. Lollipop öncesi cihazlarda da çalışır.


@TruptiNasit Bunu duyduğuma sevindim.
Shayne3000

Benim için çalıştı. Teşekkür ederim.
wesley franks

1
@wesleyfranks Rica ederim. İşe yaradığını duyduğuma sevindim.
Shayne3000

7

Böyle bir şey denedin mi?

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

getResources () işlevinin yalnızca bir etkinlikte çalışacağını unutmayın. Ancak her bağlamda da çağrılabilir.


Burada açıklandığı gibi bir xml oluşturabilirsiniz: developer.android.com/reference/android/content/res/…
Chris K.

getColorStateList kullanımdan kaldırılmış gibi görünüyor.
cloudurfin

1
setBackgroundTintList, API seviyesi 21 gerektiriyor
Nashe

1
buton. setBackgroundTintList (ContextCompat.getColorStateList (bağlam, R.color.blue)); benim için çalıştı
jesto paul


5

DrawableCompat'ı kullanabilirsiniz, örneğin

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

5

bu, malzeme tasarım kitaplığındaki yeni Malzeme Düğmesinde kolayca işlenir, önce bağımlılığı ekleyin:

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

sonra XML'nizde düğmeniz için bunu kullanın:

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

ve rengi değiştirmek istediğinizde, işte Kotlin'deki kod, Kullanımdan kaldırılmadı ve Android 21'den önce kullanılabilir:

accept.backgroundTintList = ColorStateList.valueOf(ResourcesCompat.getColor(resources, 
R.color.colorPrimary, theme))

Metnin kendisi için benzer bir renk var mı?
android geliştiricisi

Düğme olarak metni mi kastediyorsunuz ve arka planın rengini değiştirmek mi istiyorsunuz?
Amin Keshavarzian

4

Benimkini çalıştırmayı başardığım yol kullanmaktı CompoundButtonCompat.setButtonTintList(button, colour).

Anladığım kadarıyla bu, android sürümünden bağımsız olarak çalışır.


3

Benzer bir problemim vardı. Renk (int) değerine dayalı bir görünüm için karmaşık bir çekilebilir arka planı renklendirmek istedim. Şu kodu kullanarak başardım:

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

Renk, gerekli rengi temsil eden bir int değeridir. Bu, basit xml ColorStateList'i temsil eder:

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

Bu yardımcı olur umarım.


2
Minimum gerekli API seviyesi 21
forsberg

pekala kullanabilirsinizColorStateList.valueOf(ColorInt)
user924

2

ImageButton için şunları kullanabilirsiniz:

favoriteImageButton.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint

setColorFilter, Düğmeler için tanımlanmadı
Jérémy

ImageButton için öyle.
Saurabh Singh

Oh tamam, bunu bilmiyordum. Ancak OP, Button'ı istiyor. Yanıtınızı bu ayrıntıyla düzenleyebilir misiniz, böylece olumsuz oyumu kaldırabilir miyim?
Jérémy

2

Eğer kullanıyorsanız Kotlinve Material Designaşağıdaki konularda rengini değiştirebilir MaterialButtonböyle:

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

MaterialButtonKodunuzu daha okunaklı ve kodlamanızı biraz daha rahat hale getirmek için sizin için bir uzantı işlevi oluşturarak onu daha da iyileştirebilirsiniz :

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

Ardından, işlevinizi şu şekilde her yerde kullanabilirsiniz:

myButton.changeColor(R.color.myColor)

1

Shayne3000'in cevabına ek olarak bir renk kaynağı da kullanabilirsiniz (sadece int renk değil). Kotlin versiyonu:

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

0

XML tabanlı renk durumu listeniz temalı özniteliklere referans veriyorsa, burada önerilen yanıt Android 5.0'da düzgün çalışmıyor .. Örneğin, şu şekilde bir xml renk durumu listem var:

<?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>

Bunu xml'den arka planım olarak kullanmak Android 5.0 ve diğer her şeyde gayet iyi çalışıyor. Ancak bunu şu şekilde bir kodda ayarlamaya çalışırsam:

(Bunu yapma)

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

Aslında Activity'i veya düğmenin bağlamını ContextCompat.getColorStateList () yöntemine aktarmamın bir önemi yok, ne de bana düğmenin içinde olduğu temaya göre uygun renk durumu listesini vermez. Bunun nedeni, renk durumu listelerinde tema niteliklerinin kullanılmasının api 23'e kadar desteklenmemesi ve ContextCompat'ın bunları çözmek için özel bir şey yapmamasıdır. Bunun yerine , <API 23 cihazlarında kendi kaynak ayrıştırma / tema öznitelik çözümlemesini yapan AppCompatResources.getColorStateList () kullanmanız gerekir .

Bunun yerine şunu kullanmalısınız:

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

TLDR: kullanım AppCompatResources değil -ContextCompat- android tüm API sürümleri arasında çözülmesi temalı kaynağa ihtiyaç olacak olursa.

Konuyla ilgili daha fazla bilgi için bu makaleye bakın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.