如何在程序中动态添加按钮色调

220
在新的AppCompat库中,我们可以通过以下方式对按钮进行着色:

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

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


你确定 android:backgroundTint 在 Lollipop 之前的版本上能正常工作吗?我测试了 Button 和 ApCompatButton,但是 backgroundTint 只在 Lollipop 上有效。 - Sharjeel
1
请查看这个答案 - Amit Vaghela
23个回答

257
根据文档,与android:backgroundTint相关的方法是setBackgroundTintList(ColorStateList list)

更新

请点击链接了解如何创建颜色状态列表资源。

<?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的一个实例。


使用AppCompat。

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

2
不是一种颜色,而是ColorStateList。如何利用它? - Stephane Maarek
9
我理解了如何做,谢谢。但为什么Android不允许你手动使用颜色呢?对于我所有的按钮颜色,我都必须创建一个ColorStateList的xml吗?这看起来对我来说很浪费。 - Stephane Maarek
4
即使你在 AppCompatButton 上调用 setBackgroundTintList 方法,它仍需要 API 21 及以上的版本。 - Sharjeel
35
AppCompat支持库提供了一个静态助手:ViewCompat.setBackgroundTintList(View, ColorStateList),可在API 4及更早版本中使用。但它仅适用于实现了“TintableBackgroundView”的视图,例如AppCompatButton(而不是通常的Button)。 - Jon Adams
2
现在,正如@Jon Adams所建议的那样,使用ViewCompat.setBackgroundTintList(View,ColorStateList)更有意义,因为View.setSupportButtonTintList受到了RestrictTo注释的限制。详细信息请参见:https://developer.android.com/reference/android/support/annotation/RestrictTo.html - AlexKost
显示剩余4条评论

123

你可以使用

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

您可以在这篇博客文章中找到更多信息(请查看“Drawable tinting”部分)


3
你能提供使用你的方法设置色调的完整代码吗? - M. Usman Khan
这个问题是关于一个按钮,而这个答案是关于一个可绘制对象的。为什么它会显示为一个答案呢?非常具有误导性和无帮助性。 - Kaan

86
似乎视图有自己的色调管理机制,因此最好将色调列表放在这里。
ViewCompat.setBackgroundTintList(
    editText, 
    ColorStateList.valueOf(errorColor));

这种方式使用起来更好,因此您可以从API 4获得向后兼容性! - xarlymg89

39

以下是用Kotlin实现的方法:

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

注意,如果你这样做,你会设置可绘制对象的色调。因此,任何具有相同背景的视图都将被着色! - MakiX
这是针对API23及以上版本的。 - c-an

28

通过提供一个实际的代码示例,来扩展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);

这个解决方案适用于将可绘制对象用作按钮背景的场景。它也可以在 Android 5.0 之前的设备上使用。


25

简单的方法

使用Java

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

在Kotlin中
myButton.backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(context, R.color.white) )

1
resources.getColor()已经过时。 - Pravinsingh Waghela
1
最好使用ContextCompat.getColor(context, R.color.white)。 - Emad Razavi
为什么不直接使用ContextCompat.getColorStateList呢?你可以用一个函数调用来替换两个。 - undefined

12

你尝试过类似这样的东西吗?

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

请注意,getResources() 只能在活动中使用。但也可以在每个上下文中调用。


1
你可以按照这里描述的方式创建一个XML:http://developer.android.com/reference/android/content/res/ColorStateList.html - Chris K.
1
getColorStateList 似乎已经被弃用。 - cloudsurfin
2
setBackgroundTintList 似乎需要API级别21。 - EMalik
2
按钮。 setBackgroundTintList(ContextCompat.getColorStateList(context, R.color.blue)); 对我有效。 - jesto paul

9
你可以使用类似这样的东西:
myButton.backgroundTintList = AppCompatResources.getColorStateList(context, R.color.primary_variant)

8

在Material Design库中,这个问题可以轻松地通过新的Material Button来处理。首先,添加依赖项:

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

1
有没有类似的东西可以用于文本本身的色调? - android developer
1
您是指按钮的文本,并想要更改背景颜色吗? - Amin Keshavarzian

7
我成功让我的工作是通过使用CompoundButtonCompat.setButtonTintList(button, colour)实现的。
据我理解,这适用于所有Android版本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接