如何使按钮变灰?

129

我有一个如下所示的按钮。当我想要禁用它时,我使用my_btn.setEnabled(false),但我也想将其变灰。我该怎么做?

谢谢

<Button android:id="@+id/buy_btn" style="@style/srp_button" />

style/srp_button

的翻译是:

样式/srp_button

<style name="srp_button" parent="@android:style/Widget.Button">
    <item name="android:background">@drawable/btn_default</item>
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:textColor">#ffffff</item>
    <item name="android:textSize">14sp</item>
    <item name="android:typeface">serif</item>
    <item name="android:paddingLeft">30dp</item>
    <item name="android:paddingRight">30dp</item>
    <item name="android:paddingTop">5dp</item>
    <item name="android:paddingBottom">5dp</item>
</style>

drawable/btn_default.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/pink" />
    <corners android:radius="6dp" />
</shape>

2
使用选择器 https://dev59.com/GVvUa4cB1Zd3GeqPpgob - Buda Gavril
9个回答

196

您也可以通过设置透明度(使其半透明)将其显示为禁用状态。如果您的按钮背景是图像,并且不想为其创建状态,则特别有用。

button.setAlpha(.5f);
button.setClickable(false);
更新:我在 Kotlin 出现之前以及我还是个新手时编写了上述解决方案。它更多地是一个“快速而粗略”的解决方案,但我不建议在专业环境中使用它。
今天,如果我想要一个通用的解决方案,可以在不必创建状态列表的情况下适用于任何按钮/视图,我会创建一个 Kotlin 扩展。
fun View.disable() {
    getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY)
    setClickable(false)
}

在Java中,你可以使用类似于静态工具函数的方式来实现某种功能,只需将视图作为变量传递即可。虽然不够简洁,但它是有效的。


4
我曾经阅读过,调用setAlpha函数会消耗大量的CPU资源。有人能够证实吗? - Ali Kazi
@AliKazi 这取决于你的 View 的类型。根据 这篇 G+ 帖子: "如果您的 View 不包含重叠的绘图命令,则 setAlpha() 会被优化掉,我们只需修改 Paint 对象以应用适当的 alpha。当 View.hasOverlappingRendering() 返回 true 时会发生这种情况。ImageView 和没有背景 drawable 的 TextView 是这种优化的常见候选项。如果您处于这种情况,请随意使用 setAlpha()。"。 - Sufian
1
@Sufian 谢谢。但为了更安全起见,我对每个按钮都依赖于一个简单的StateListDrawable。我是如何做到这一点的,我已经发布了一个新答案。我还包括了我学习alpha会影响性能的链接。 - Ali Kazi
那实际上会使视图失效。谢谢@Siavash - Akash Bisariya
1
@IgorGanapolsky 是的,请看下面的答案(使用选择器xml)。但是,如果你刚开始学习Android,我强烈建议学习Android Compose而不是布局。布局将在几年内过时。 - Siavash
显示剩余3条评论

66

btn_default.xml中,您需要提供3或4种状态作为选择器。

  1. 按下状态
  2. 默认状态
  3. 焦点状态
  4. 启用状态(使用false指示的禁用状态,请参见注释)

您将相应地为这些状态提供效果和背景。

以下是详细讨论:标准Android按钮,使用不同颜色


那么为了将其变灰,我必须更改禁用状态下的背景颜色和文本颜色吗?没有办法只添加透明前景吗? - jul
3
是的!当您提供 android:state_disable="true" 时,它将展示按钮被禁用时的状态,这是简单且推荐的方式。 - Adil Soomro
1
我在哪里可以指定禁用状态下的文本颜色?似乎只能指定背景...我为此提出了一个新问题:https://dev59.com/MWoy5IYBdhLWcg3wJKzR - jul
22
有没有 android:state_disable="true"?你是指 android:state_enabled="false" 吗? - caw
@MarcoW.:是的,你完全正确。对于错误的属性表示道歉。 - Adil Soomro
答案不应该被更正吗?这个建议可以吗?http://stackoverflow.com/review/suggested-edits/5468508 - brasofilo

61

最简单的解决方案是将按钮的背景图像设置为颜色过滤器,就像我在这里看到的。

你可以按照以下步骤操作:

if ('need to set button disable')
    button.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
else
    button.getBackground().setColorFilter(null);

希望我能帮助到某人...


我最喜欢这种方法。谢谢! - edhnb
2
这种方法有潜力,但最终的颜色并不总是你所期望的。例如,一个橙色按钮与灰色相乘的结果是深红色,而不是褪色的橙色。 - Someone Somewhere
4
也许应该使用Mode.SRC_IN而不是乘法。请参考https://dev59.com/Fmw05IYBdhLWcg3weBlF#17112876。 - Someone Somewhere
这个可以运行,但是两种颜色混合在一起会变成另一种颜色。 - Shamsul Arefin
太棒了!非常干净。 - Milind Chaudhary

36

所有给定的答案都很好,但我记得学习过使用setAlpha在性能方面可能是一个不好的想法(更多信息在这里)。因此,创建一个StateListDrawable是更好的想法来管理按钮的禁用状态。以下是方法:

在res/drawable文件夹中创建一个名为btn_blue.xml的XML文件:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Disable background -->
    <item android:state_enabled="false"
          android:color="@color/md_blue_200"/>
    
    <!-- Enabled background -->
    <item android:color="@color/md_blue_500"/>
</selector>

在res/values/styles.xml中创建一个按钮样式。
<style name="BlueButton" parent="ThemeOverlay.AppCompat">
      <item name="colorButtonNormal">@drawable/btn_blue</item>
      <item name="android:textColor">@color/md_white_1000</item>
</style>

然后将此样式应用于您的按钮:
<Button
     android:id="@+id/my_disabled_button"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:theme="@style/BlueButton"/>

现在,当你调用btnBlue.setEnabled(true)或者btnBlue.setEnabled(false)时,状态颜色会自动切换。

17

你应该为禁用按钮创建一个 XML 文件 (drawable/btn_disable.xml)

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/grey" />
    <corners android:radius="6dp" />
</shape>

创建按钮的选择器(drawable/btn_selector.xml)。

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/btn_disable" android:state_enabled="false"/>
    <item android:drawable="@drawable/btn_default" android:state_enabled="true"/>
    <item android:drawable="@drawable/btn_default" android:state_pressed="false" />

</selector>

将选择器添加到您的按钮中

<style name="srp_button" parent="@android:style/Widget.Button">
    <item name="android:background">@drawable/btn_selector</item>
</style>

13

将Clickable属性设置为false,并将背景颜色更改为:

callButton.setClickable(false);
callButton.setBackgroundColor(Color.parseColor("#808080"));

4

我尝试了上述的解决方案,但是似乎没有一个对我起作用。最终我采用了以下选项:

<!-- button_color_selector.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorAccent" android:state_enabled="true"/>
    <item android:color="@color/colorAccentLight" android:state_enabled="false"/>
</selector>

<com.google.android.material.button.MaterialButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:backgroundTint="@color/button_color_selector"
                .../>

2
我用了这段代码来实现这个功能:
ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
profilePicture.setColorFilter(filter);

0
Button button = (Button)findViewById(R.id.buy_btn);
button.setEnabled(false);

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