具有不同颜色的标准 Android 按钮
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1521640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Standard Android Button with a different color
提问by emmby
I'd like to change the color of a standard Android button slightly in order to better match a client's branding.
我想稍微更改标准 Android 按钮的颜色,以便更好地匹配客户的品牌。
The best way I've found to do this so far is to change the Button
's drawable to the drawable located in res/drawable/red_button.xml
:
到目前为止,我发现这样做的最佳方法是将Button
的可绘制更改为位于以下位置的可绘制res/drawable/red_button.xml
:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/red_button_pressed" />
<item android:state_focused="true" android:drawable="@drawable/red_button_focus" />
<item android:drawable="@drawable/red_button_rest" />
</selector>
But doing that requires that I actually create three different drawables for each button I want to customize (one for the button at rest, one when focused, and one when pressed). That seems more complicated and non-DRY than I need.
但是这样做需要我为我想要自定义的每个按钮实际创建三个不同的可绘制对象(一个用于静止的按钮,一个用于聚焦时,一个用于按下时)。这似乎比我需要的更复杂和非 DRY。
All I really want to do is apply some sort of color transform to the button. Is there an easier way to go about changing a button's color than I'm doing?
我真正想做的就是对按钮应用某种颜色变换。有没有比我正在做的更简单的方法来改变按钮的颜色?
采纳答案by emmby
I discovered that this can all be done in one file fairly easily. Put something like the following code in a file named custom_button.xml
and then set background="@drawable/custom_button"
in your button view:
我发现这一切都可以很容易地在一个文件中完成。将类似以下代码的内容放在一个名为的文件中custom_button.xml
,然后background="@drawable/custom_button"
在按钮视图中进行设置:
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape>
<gradient
android:startColor="@color/yellow1"
android:endColor="@color/yellow2"
android:angle="270" />
<stroke
android:width="3dp"
android:color="@color/grey05" />
<corners
android:radius="3dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
<item android:state_focused="true" >
<shape>
<gradient
android:endColor="@color/orange4"
android:startColor="@color/orange5"
android:angle="270" />
<stroke
android:width="3dp"
android:color="@color/grey05" />
<corners
android:radius="3dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:endColor="@color/blue2"
android:startColor="@color/blue25"
android:angle="270" />
<stroke
android:width="3dp"
android:color="@color/grey05" />
<corners
android:radius="3dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
</selector>
回答by conjugatedirection
Following on from Tomasz's answer, you can also programmatically set the shade of the entire button using the PorterDuff multiply mode. This will change the button colour rather than just the tint.
继 Tomasz 的回答之后,您还可以使用 PorterDuff 乘法模式以编程方式设置整个按钮的阴影。这将改变按钮颜色而不仅仅是色调。
If you start with a standard grey shaded button:
如果您从标准的灰色阴影按钮开始:
button.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
will give you a red shaded button,
会给你一个红色阴影按钮,
button.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);
will give you a green shaded button etc., where the first value is the colour in hex format.
会给你一个绿色阴影按钮等,其中第一个值是十六进制格式的颜色。
It works by multiplying the current button colour value by your colour value. I'm sure there's also a lot more you can do with these modes.
它的工作原理是将当前按钮颜色值乘以您的颜色值。我敢肯定,您还可以使用这些模式做更多事情。
回答by Tomasz
Mike, you might be interested in color filters.
迈克,你可能对滤色器感兴趣。
An example:
一个例子:
button.getBackground().setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0xFFAA0000));
try this to achieve the color you want.
试试这个来达到你想要的颜色。
回答by RediOne1
This is my solution which perfectly works starting from API 15. This solution keeps all default button click effects, like material RippleEffect
. I have not tested it on lower APIs, but it should work.
这是我从 API 15开始完美运行的解决方案。此解决方案保留所有默认按钮单击效果,例如 material RippleEffect
。我没有在较低的 API 上测试过它,但它应该可以工作。
All you need to do, is:
您需要做的就是:
1) Create a style which changes only colorAccent
:
1)创建一个只改变的样式colorAccent
:
<style name="Facebook.Button" parent="ThemeOverlay.AppCompat">
<item name="colorAccent">@color/com_facebook_blue</item>
</style>
I recommend using
ThemeOverlay.AppCompat
or your mainAppTheme
as parent, to keep the rest of your styles.
我建议使用
ThemeOverlay.AppCompat
或 您的主要AppTheme
作为父级,以保留其余样式。
2) Add these two lines to your button
widget:
2) 将这两行添加到您的button
小部件中:
style="@style/Widget.AppCompat.Button.Colored"
android:theme="@style/Facebook.Button"
Sometimes your new
colorAccent
isn't showing in Android Studio Preview, but when you launch your app on the phone, the color will be changed.
有时您的新
colorAccent
内容不会显示在 Android Studio Preview 中,但是当您在手机上启动您的应用程序时,颜色会发生变化。
Sample Button widget
示例按钮小部件
<Button
android:id="@+id/sign_in_with_facebook"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/sign_in_facebook"
android:textColor="@android:color/white"
android:theme="@style/Facebook.Button" />
回答by Nilhcem
You can now also use appcompat-v7's AppCompatButtonwith the backgroundTint
attribute:
您现在还可以使用带有属性的appcompat-v7 的AppCompatButtonbackgroundTint
:
<android.support.v7.widget.AppCompatButton
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:backgroundTint="#ffaa00"/>
回答by Stan Kurdziel
I like the color filter suggestion in previous answers from @conjugatedirection and @Tomasz; However, I found that the code provided so far wasn't as easily applied as I expected.
我喜欢@共轭方向和@Tomasz 以前的答案中的滤色器建议;但是,我发现到目前为止提供的代码并不像我预期的那样容易应用。
First, it wasn't mentioned whereto apply and clear the color filter. It's possible that there are other good places to do this, but what came to mind for me was an OnTouchListener.
首先,没有提到在哪里应用和清除滤色器。可能还有其他好地方可以做到这一点,但我想到的是OnTouchListener。
From my reading of the original question, the ideal solution would be one that does not involve any images. The accepted answer using custom_button.xml from @emmby is probably a better fit than color filters if that's your goal. In my case, I'm starting with a png image from a UI designer of what the button is supposed to look like. If I set the button background to this image, the default highlight feedback is lost completely. This code replaces that behavior with a programmatic darkening effect.
从我对原始问题的阅读来看,理想的解决方案是不涉及任何图像的解决方案。如果这是您的目标,那么使用来自 @emmby 的 custom_button.xml 的公认答案可能比滤色器更合适。就我而言,我从 UI 设计师的 png 图像开始,说明按钮应该是什么样子。如果我将按钮背景设置为此图像,则默认的高亮反馈将完全丢失。此代码用编程变暗效果替换了该行为。
button.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 0x6D6D6D sets how much to darken - tweak as desired
setColorFilter(v, 0x6D6D6D);
break;
// remove the filter when moving off the button
// the same way a selector implementation would
case MotionEvent.ACTION_MOVE:
Rect r = new Rect();
v.getLocalVisibleRect(r);
if (!r.contains((int) event.getX(), (int) event.getY())) {
setColorFilter(v, null);
}
break;
case MotionEvent.ACTION_OUTSIDE:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
setColorFilter(v, null);
break;
}
return false;
}
private void setColorFilter(View v, Integer filter) {
if (filter == null) v.getBackground().clearColorFilter();
else {
// To lighten instead of darken, try this:
// LightingColorFilter lighten = new LightingColorFilter(0xFFFFFF, filter);
LightingColorFilter darken = new LightingColorFilter(filter, 0x000000);
v.getBackground().setColorFilter(darken);
}
// required on Android 2.3.7 for filter change to take effect (but not on 4.0.4)
v.getBackground().invalidateSelf();
}
});
I extracted this as a separate class for application to multiple buttons - shown as anonymous inner class just to get the idea.
我将它提取为一个单独的类,用于应用到多个按钮 - 显示为匿名内部类只是为了得到这个想法。
回答by haemish
If you are making colour buttons with XML you can make the code a bit cleaner by specifying the focused and pressed state in a separate file and reuse them. My green button looks like this:
如果您使用 XML 制作颜色按钮,您可以通过在单独的文件中指定聚焦和按下状态并重用它们来使代码更简洁一些。我的绿色按钮如下所示:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="@drawable/button_focused"/>
<item android:state_pressed="true" android:drawable="@drawable/button_pressed"/>
<item>
<shape>
<gradient android:startColor="#ff00ff00" android:endColor="#bb00ff00" android:angle="270" />
<stroke android:width="1dp" android:color="#bb00ff00" />
<corners android:radius="3dp" />
<padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
</shape>
</item>
</selector>
回答by user1185087
The shortest solution which is working with any Android version:
适用于任何 Android 版本的最短解决方案:
<Button
app:backgroundTint="@color/my_color"
Notes/Requirements:
注意事项/要求:
- Use the
app:
namespace and nottheandroid:
namespace! appcompat version > 24.2.0
dependencies { compile 'com.android.support:appcompat-v7:25.3.1' }
- 使用
app:
命名空间和没有的android:
命名空间! 应用兼容版本 > 24.2.0
依赖{编译'com.android.support:appcompat-v7:25.3.1'}
回答by Kelok Chan
I am using this approach
我正在使用这种方法
style.xml
样式文件
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:colorPrimaryDark">#413152</item>
<item name="android:colorPrimary">#534364</item>
<item name="android:colorAccent">#534364</item>
<item name="android:buttonStyle">@style/MyButtonStyle</item>
</style>
<style name="MyButtonStyle" parent="Widget.AppCompat.Button.Colored">
<item name="android:colorButtonNormal">#534364</item>
<item name="android:textColor">#ffffff</item>
</style>
As you can see from above, I'm using a custom style for my button. The button color corresponds to the accent color. I find this a much better approach than setting android:background
as I won't lose the ripple effect Google provides.
从上面可以看出,我为我的按钮使用了自定义样式。按钮颜色对应于强调色。我发现这是一种比设置更好的方法,android:background
因为我不会失去 Google 提供的连锁反应。
回答by IntelliJ Amiya
Use it in this way:
以这种方式使用它:
buttonOBJ.getBackground().setColorFilter(Color.parseColor("#YOUR_HEX_COLOR_CODE"), PorterDuff.Mode.MULTIPLY);