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


118

在新的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在Pre-Lollipop上运行吗?我同时测试了Button和ApCompatButton,但是backgroundTint似乎只能在Lollipop上运行。
Sharj 2015年

1

Answers:


159

根据文档,相关的方法android:backgroundTintsetBackgroundTintList(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));

contextInstance一个实例在哪里Context


使用AppCompart

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

这不是颜色,而是ColorStateList。如何利用它?
Stephane 2015年

4
我现在知道如何做,但是为什么Android不允许您仅手动使用颜色?对于我拥有的每个按钮的每种颜色,我都必须为ColorStateList创建一个xml吗?这对我来说似乎是一种浪费
Stephane 2015年

2
setBackgroundTintList即使在AppCompatButton上调用也需要API 21。
Sharj 2015年

29
AppCompat支持库提供了一个静态帮助器:ViewCompat.setBackgroundTintList(View, ColorStateList)可以一直使用到API4。但是它仅适用于实现的视图(TintableBackgroundView例如AppCompatButton,而不是通常的Button)。
乔恩·亚当斯

1
现在,使用ViewCompat.setBackgroundTintList(View, ColorStateList)@Jon Adams建议的方法更有意义,因为View.setSupportButtonTintList受RestrictTo注释限制。此处的详细信息:developer.android.com/reference/android/support/annotation/…–
AlexKost

75

你可以用

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

您可以在此博客文章中找到更多信息(请参见“可绘制着色”部分)


2
您能提供使用ur方法设置色调的完整代码吗?
M. Usman Khan

最佳答案...!
Gokul Nath KP

60

似乎视图具有自己的色调管理机制,因此更好的将放在色调列表中:

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

这样更好地使用它,因此您可以从API 4向后兼容!
xarlymg89

最好的解决方案之一。
Atif AbbAsi

20

通过提供真实的代码情况来适当扩展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用作按钮背景的情况。它也可以在棒棒糖之前的设备上使用。


@TruptiNasit很高兴听到这个消息。
Shayne3000 '18

为我工作。谢谢。
韦斯利

1
@wesleyfranks不客气。很高兴听到它奏效。
Shayne3000 '19

7

你尝试过这样的事情吗?

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

请注意,getResources()仅在活动中起作用。但是也可以在每种情况下调用它。


:这里描述,您可以创建一个XML developer.android.com/reference/android/content/res/...
克里斯K.

getColorStateList似乎已被弃用。
cloudurfin

1
setBackgroundTintList似乎需要API级别21
Nashe

1
按钮。setBackgroundTintList(ContextCompat.getColorStateList(context,R.color.blue)); 为我工作
jesto paul 2016年


5

您可以使用DrawableCompat例如

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

5

这可以在材料设计库的新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))

文字色彩本身是否也有类似的文字?
Android开发人员

您的意思是将文本作为按钮,并且想要更改背景颜色?
阿敏·凯沙瓦尔兹安

4

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

据我了解,无论Android版本如何,此方法均有效。


3

我有一个类似的问题。我希望基于颜色(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>

希望这可以帮助。


2
最低要求的API级别21
forsberg

好,您可以使用ColorStateList.valueOf(ColorInt)
user924

2

对于ImageButton,您可以使用:

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

setColorFilter没有为按钮定义
杰里米

是的,用于ImageButton。
萨拉·辛格

哦,好,我不知道。但是OP要求Button。您可以使用此详细信息编辑答案,以便我删除我的否决票吗?
杰里米

2

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

1

除了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

0

如果您的基于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()在设备<API 23上执行自己的资源解析/主题属性解析。

相反,您必须使用以下命令:

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

TLDR:使用AppCompatResources如果您需要在所有API版本的android中解析主题资源,请而不是-ContextCompat-。

有关该主题的更多信息,请参见本文

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.