Как добавить оттенок кнопки программно

В новой библиотеке AppCompat мы можем подкрасить кнопку следующим образом:

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

Как программно настроить оттенок кнопки в моем коде? Я в основном пытаюсь реализовать условную раскраску кнопки на основе некоторого пользовательского ввода.

23 ответа

Решение

Согласно документации, соответствующий метод android:backgroundTint is setBackgroundTintList (список ColorStateList)

Обновить

Перейдите по этой ссылке, чтобы узнать, как создать ресурс списка состояний цвета.

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

затем загрузите его, используя

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

где contextInstance является примером Context


используя AppCompart

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

Вы могли бы использовать

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

Но я бы порекомендовал вам использовать библиотеку поддержки рисования, которая только что была выпущена вчера:

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

Вы можете найти больше в этом сообщении в блоге (см. Раздел "Тонирование по цвету")

Похоже, что представления имеют собственную механику для управления оттенками, поэтому лучше будет добавить список оттенков:

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

Вот как это сделать в котлине:

view.background.setTint(ContextCompat.getColor(context, textColor))

Правильно расширив ответ dimsuz, предоставив реальную ситуацию с кодом, см. Следующий фрагмент кода:

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

Это решение для сценария, в котором в качестве фона кнопки используется рисование. Он также работает на устройствах перед леденцом на палочке.


Самый простой способ сделать это

в Java

myButton.setBackgroundTintList(ColorStateList.valueOf(resources.getColor(R.id.white)));

в Котлине

myButton.setBackgroundTintList(ColorStateList.valueOf(resources.getColor(R.id.white)))

Вы пробовали что-то подобное?

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

обратите внимание, что getResources() будет работать только в действии. Но это может быть вызвано и в любом контексте.

Вы можете использовать что-то вроде этого:

      myButton.backgroundTintList = AppCompatResources.getColorStateList(context, R.color.primary_variant)

Это легко сделать с помощью новой кнопки "Материал" из библиотеки материалов. Сначала добавьте зависимость:

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

затем в вашем XML, используйте это для вашей кнопки:

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

и когда вы хотите изменить цвет, вот код в Kotlin, он не устарел и может использоваться до Android 21:

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

Мне удалось заставить мою работу работать с помощью CompoundButtonCompat.setButtonTintList(button, colour),

Насколько я понимаю, это работает независимо от версии Android.

Вы можете использовать DrawableCompat, например

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

Если вы используете Kotlin а также Material Design, вы можете изменить цвет вашего MaterialButton нравится:

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

Вы можете улучшить его еще лучше, создав функцию расширения для своего MaterialButton чтобы код был более читабельным, а кодирование - немного более удобным:

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

Затем вы можете использовать свою функцию везде следующим образом:

myButton.changeColor(R.color.myColor)

У меня была похожая проблема. Я хотел покрасить сложный нарисованный фон для вида на основе значения цвета (int). Мне удалось с помощью кода:

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

Где color - это значение типа int, представляющее требуемый цвет. Это представляет простой XML ColorStateList:

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

Надеюсь это поможет.

Для ImageButton вы можете использовать:

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

В дополнение к ответу Shayne3000 вы также можете использовать ресурс цвета (не только цвет int). Версия Котлина:

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

Есть три варианта использования setBackgroundTintList

int myColor = Color.BLACK;
  1. button.setBackgroundTintList(new ColorStateList(EMPTY, new int[] { myColor }));
  2. button.setBackgroundTintList(ColorStateList.valueOf(myColor));
  3. button.setBackgroundTintList(contextInstance.getResources().getColorStateList(R.color.my_color));

Предлагаемый ответ не работает должным образом на Android 5.0, если ваш список состояний цвета на основе XML ссылается на тематические атрибуты. Например, у меня есть список состояний цвета xml, например:

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

Использование этого в качестве фона backgroundTint из xml прекрасно работает на Android 5.0 и во всем остальном. Однако, если я попытаюсь установить это в коде так:

(Не делай этого)

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

На самом деле это не имеет значения, если я передам Activity или контекст кнопки методу ContextCompat.getColorStateList(), ни то, ни другое не даст мне правильный список состояний цвета относительно темы, в которой находится кнопка. Это связано с тем, что использование атрибутов темы в списках состояний цветов не поддерживалось до тех пор, пока API 23 и ContextCompat не предпримут ничего особенного для их разрешения. Вместо этого вы должны использовать AppCompatResources.getColorStateList (), который выполняет собственный анализ ресурсов / разрешение атрибутов темы на устройствах

Вместо этого вы должны использовать это:

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

TLDR: используйте AppCompatResources, а не -ContextCompat-, если вам нужны разрешенные тематические ресурсы для всех версий API android.

Для получения дополнительной информации по этой теме, см. Эту статью.

Если вы не хотите заботиться о разных версиях Android, вы можете использовать этот код практически для любого представления. Работал на меня.

      val states = arrayOf(intArrayOf(android.R.attr.state_enabled))
                    val colors = intArrayOf(Color.GREEN) // your color here
                    val colorStateList = ColorStateList(states, colors)
                  ViewCompat.setBackgroundTintList(yourButtonHere,colorStateList)

Версия Kotlin, желаю хорошего дня всем, кто это читает ;)

кстати. если вы создали какую-то форму фона, которую можно рисовать, это должно переопределить только цвет оттенка.

      checkbox.ButtonTintList = ColorStateList.ValueOf(Android.Color.White);

Использовать ButtonTintList вместо BackgroundTintList

filterBtn.setBackgroundTintList(ContextCompat.getColorStateList(контекст,R.color.colorPrimary))

простой, мы также можем использовать для просмотра изображений

          imageView.setColorFilter(ContextCompat.getColor(context,
R.color.COLOR_YOUR_COLOR));

Если кто-то хочет знать, как установить цветовой код HTML в оттенке фона (в моем случае цветовой код поступает из серверной части)

      String htmlColorCode = "#FF0000";
int colorInt = Color.parseColor(htmlColorCode);
View myView = findViewById(R.id.my_view);
ViewCompat.setBackgroundTintList(myView, ColorStateList.valueOf(colorInt));

С Котлином,

      checkbox.buttonTintList = AppCompatResources.getColorStateList(context, color.colorPrimary)
Другие вопросы по тегам