我一直在使用Android的Google设计支持库。为了设置与应用程序主题不同的按钮颜色,我在布局XML文件中声明按钮,如下所示:

<Button
            style="@style/Widget.AppCompat.Button.Colored"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:theme="@style/MyButton" />

然后在styles.xml中将MyButton定义为
<style name="MyButton" parent="ThemeOverlay.AppCompat">
    <item name="colorButtonNormal">@color/my_color</item>
</style>

这给了我一个根据设计支持库的按钮,其背景颜色是我的colors.xml文件中用@color/my_color定义的背景颜色。

因此,基本上是使用android:theme更改colorButtonNormal属性以获得所需的颜色。

如何以编程方式获得相同的结果?基本上,如果我可以做类似的事情
myButton.setTheme(R.style.MyButton)

...然后我可以设置colorButtonNormal来获取 View 。

我无法将其设置为
myButton.setBackgroundColor(ContextCompat.getColor(getContext(),R.color.my_color));

甚至不喜欢
ColorStateList colorStateList = ContextCompat.getColorStateList(getActivity(), R.color.my_color);
ViewCompat.setBackgroundTintList(myButton, colorStateList);

这将消除设计支持库的触摸效果。

最佳答案

对于Button,我编写了以下帮助程序方法:

public static ColorStateList getButtonColorStateList(Context context, int accentColor) {
    // get darker variant of accentColor for button pressed state
    float[] colorHSV = new float[3];
    Color.colorToHSV(accentColor, colorHSV);
    colorHSV[2] *= 0.9f;
    int darkerAccent = Color.HSVToColor(colorHSV);

    return new ColorStateList(
            new int[][] {{android.R.attr.state_pressed}, {android.R.attr.state_enabled}, {-android.R.attr.state_enabled}},
            new int[] { darkerAccent, accentColor, getColor(context, R.color.buttonColorDisabled) });
}

accentColor是正常启用状态的颜色值。对于按下状态,使用accentColor的深色变体;对于禁用状态,我在值中定义了颜色:
<color name="buttonColorDisabled">#dddddd</color>

使用此方法:
mButton.setSupportBackgroundTintList(Utils.getButtonColorStateList(this, accentColor));

其中mButton是AppCompatButton,而accentColor是color的值。

这对我来说对 Lollipop 及以上具有触觉效果,对 Lollipop 前和标准变色效果均有效。

10-07 13:46
查看更多