如何以编程方式添加按钮色调

How to add button tint programmatically

在新的 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"
    />

如何在我的代码中以编程方式设置按钮的色调? 我基本上是在尝试根据某些用户输入实现按钮的条件着色。

根据 documentation the related method to android:backgroundTint is setBackgroundTintList(ColorStateList list)

更新

按照此 link 了解如何创建颜色状态列表资源。

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

其中 contextInstanceContext

的实例

使用 AppCompart

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

你试过这样的东西吗?

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

请注意,getResources() 仅适用于 activity。但它也可以在每个上下文中调用。

你可以使用

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

您可以找到更多 in this blog post(参见 "Drawable tinting" 部分)

您可以使用 DrawableCompat,例如

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

我遇到了类似的问题。我希望根据颜色 (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>

希望对您有所帮助。

似乎视图有自己的色调管理机制,所以最好将色调列表放在:

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

对于 ImageButton,您可以使用:

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

我设法让我的工作的方法是使用 CompoundButtonCompat.setButtonTintList(button, colour)

据我了解,无论 android 版本如何,这都有效。

通过提供真实的代码情况来正确扩展 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);

此方案适用于drawable作为按钮背景的场景。它也适用于 pre-Lollipop 设备。

这在 material 设计库的新 Material 按钮中很容易处理,首先,添加依赖项:

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

如果您基于 XML 的颜色状态列表引用主题属性,则此处建议的答案在 android 5.0 上无法正常工作。 例如,我有一个 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>

将其用作 xml 的 backgroundTint 在 android 5.0 和其他所有系统上都可以正常工作。但是,如果我尝试在这样的代码中设置它:

(不要这样做)

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

如果我将 Activity 或按钮的上下文传递给 ContextCompat.getColorStateList() 方法实际上并不重要,两者都不会给我关于按钮主题的正确颜色状态列表在里面。这是因为在 api 23 之前不支持在颜色状态列表中使用主题属性,并且 ContextCompat 没有做任何特殊的事情来解决这些问题。相反,您必须使用 AppCompatResources.getColorStateList() 它在设备上执行自己的资源 parsing/theme 属性解析 < API 23.

相反,你必须使用这个:

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

TLDR:使用 AppCompatResources 而不是 -ContextCompat- 如果您需要跨所有 API 版本的 android.[=14 解决主题资源=]

有关该主题的更多信息,see this article

以下是在 kotlin 中的实现方法:

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

如果您使用 KotlinMaterial 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)

除了 Shayne3000 的回答之外,您还可以使用颜色资源(不仅是 int 颜色)。 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

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

简单的方法

在Java

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

在 Kotlin 中

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

简单我们也可以用于图像视图

    imageView.setColorFilter(ContextCompat.getColor(context,
R.color.COLOR_YOUR_COLOR));
checkbox.ButtonTintList = ColorStateList.ValueOf(Android.Color.White);

使用ButtonTintList代替BackgroundTintList

Tint 可以像这样添加到按钮:

filterBtn.setBackgroundTintList(ContextCompat.getColorStateList(context,R.color.colorPrimary))

如果您不想关心 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 版本,祝大家阅读愉快 ;)

顺便说一句。如果您创建了一些可绘制的背景形状,这应该只覆盖色调颜色。

你可以使用类似的东西:

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

使用 Kotlin,

checkbox.buttonTintList = AppCompatResources.getColorStateList(context, color.colorPrimary)