在新的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版本中解析主题资源。

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

其他回答

对于ImageButton,您可以使用:

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

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

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

通过提供一个真实的代码情况来适当地扩展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的相关方法: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));

哪里contextInstance是一个Context的实例


使用AppCompart

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

建议的答案在这里不能正常工作在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版本中解析主题资源。

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