使用AppCompat设计效果的Android按钮,如何在程序中动态设置buttonColorNormal?

5

我一直在使用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来获取视图,那就好了。

但是我不能像这样设置它:

myButton.setBackgroundColor(ContextCompat.getColor(getContext(),R.color.my_color));

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

这将移除设计支持库对触摸的影响。

你试过使用setBackgroundTintList吗? - JEY
按照文档操作但不起作用。已更新问题以供参考。 - Tejas Sherdiwala
你最好的选择可能是使用以下其中一个构造函数来编程创建按钮:Button(Context, AttributeSet, int defStyleAttr) Button(Context AttributeSet int defStyleAttr, int defStyleRes)。 - JEY
2个回答

1

我写了一个帮助方法,用于按钮:

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的较暗变体,对于禁用状态,我在values中定义了颜色。

<color name="buttonColorDisabled">#dddddd</color>

使用此方法:

mButton.setSupportBackgroundTintList(Utils.getButtonColorStateList(this, accentColor));

mButton是AppCompatButton,accentColor是颜色的值。

在Lollipop及以上版本中,通过触摸实现效果,而在pre-Lollipop中则作为标准颜色更改。


@PetrDana。这会消除我们在Lollipop及以上版本上的按钮点击产生的涟漪效果吗? - Tejas Sherdiwala
@Tejas 涟漪效果被保留。 - Petr Daňa

0
如果您只需要一种颜色(而不考虑状态),您可以使用:
Button button = ...;
int color = ...;
ViewCompat.setBackgroundTintList(button, ColorStateList.valueOf(color));

这将保留Lollipop及更高版本设备(API 21+)上的涟漪效果。


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