我一直在使用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 前和标准变色效果均有效。