在新的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 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 from xml在android 5.0和其他任何东西上都很好。然而,如果我试图在代码中这样设置:

(不要这样做)

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

It actually doesn't matter if I pass the Activity or the button's context to ContextCompat.getColorStateList() method, neither will give me the proper color state list with respect to the theme the button is within. This is because using theme attributes in color state lists wasn't supported until api 23 and ContextCompat does not do anything special to resolve these. Instead you must use AppCompatResources.getColorStateList() which does its own resource parsing/theme attribute resolution on devices < API 23.

相反,你必须这样做:

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

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

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

其他回答

芬兰湾的科特林,

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

你可以使用DrawableCompat。

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

通过提供一个真实的代码情况来适当地扩展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,如果你的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 from xml在android 5.0和其他任何东西上都很好。然而,如果我试图在代码中这样设置:

(不要这样做)

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

It actually doesn't matter if I pass the Activity or the button's context to ContextCompat.getColorStateList() method, neither will give me the proper color state list with respect to the theme the button is within. This is because using theme attributes in color state lists wasn't supported until api 23 and ContextCompat does not do anything special to resolve these. Instead you must use AppCompatResources.getColorStateList() which does its own resource parsing/theme attribute resolution on devices < API 23.

相反,你必须这样做:

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

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

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

下面是如何在kotlin中做到这一点:

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