禁用状态的 Material 按钮颜色

56

在Material Spec中,禁用状态的按钮呈现为灰色。

https://www.material.io/design/components/buttons.html#toggle-button

我正在使用来自Android Material Components的MaterialButton:https://www.material.io/develop/android/components/material-button/

然而,在将按钮设置为禁用时,按钮的颜色/色调不会改变。

<com.google.android.material.button.MaterialButton
    android:id="@+id/disabled_material_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:enabled="false"
    android:text="@string/button_label_disabled"/>

默认情况下Material Android组件中没有实现吗?Material Components定义了一个禁用按钮状态列表吗?

6个回答

88
  1. 在您的res目录下创建文件夹/res/color
  2. 在此处添加一个新的颜色资源文件,命名为类似color_states_materialbutton.xml的名称:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false"
        android:color="@color/colorDisabled"  />
    <item android:color="@color/colorEnabled" />
</selector>
  1. styles.xml 中创建一个样式,将其中一个 Widget.MaterialComponents.Button 样式作为父样式,并将你的颜色状态列表作为 backgroundTint 标签:
<style name="MaterialButtonStyle" parent="Widget.MaterialComponents.Button.UnelevatedButton">
        <item name="backgroundTint">@color/color_states_materialbutton</item>
</style>
  1. 在布局中设置MaterialButton的样式:
<com.google.android.material.button.MaterialButton
    style="@style/MaterialButtonStyle"
    android:id="@+id/disabled_material_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:enabled="false"
    android:text="@string/button_label_disabled"/>

谢谢。这是最好的答案。此外,我们可以直接在按钮的xml代码中使用app:backgroundTint="@color/my_color"。 - Saeid Z
我建议在样式的父级中使用 parent="ThemeOverlay.Material3.Button",以保持按钮功能(如涟漪效果)正常工作。 - Panos Gr

23
使用默认样式 Widget.MaterialComponents.Button默认选择器被用作backgroundTint。它可以处理禁用状态而无需更改:
这是默认选择器:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="?attr/colorPrimary" android:state_enabled="true"/>
  <item android:alpha="0.12" android:color="?attr/colorOnSurface"/>
</selector>

只需使用:

    <com.google.android.material.button.MaterialButton
        android:enabled="false"
        ..>

在此输入图片描述

如果您想要 更改 禁用状态的颜色,您可以使用自定义选择器。

    <com.google.android.material.button.MaterialButton
        app:backgroundTint="@color/my_selector"
        ..>

或者您可以覆盖默认选择器中使用的颜色:

    <com.google.android.material.button.MaterialButton
        android:theme="@style/button_overlay"
        ..>

使用:

    <style name="button_overlay">
       <item name="colorOnSurface">@color/my_color</item>
    </style>

<item name="colorOnSurface">@color/my_color</item> 这段代码是什么意思?它对 MaterialButton 有什么影响吗? - user924
你如何区分文本和背景颜色?我不得不制作一个单独的文件。有更直接的方法吗? - SMBiggs

6
  1. 在您的 res 文件夹中创建一个名为 "color" 的Android 资源目录(参见附图)。
  2. 创建一个名为 "button_disabled" 的颜色资源文件(参见附图)。
  3. 将以下代码放入 button_disabled.xml 文件中。
<?xml version="1.0" encoding="utf-8"?>
        <selector xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:state_enabled="false" android:color="#FD7E14" android:alpha="0.45"   />
            <item android:color="#FD7E14" />
        </selector>
  1. 找到您的values/styles.xml文件并添加以下代码
<style name="AppMaterialButton" parent="Widget.MaterialComponents.Button.UnelevatedButton">  <item name="android:backgroundTint">@color/button_disabled</item> </style>

前往您的布局/layout_文件名.xml文件并将android:enabled="false" 添加到按钮小部件中。
<com.google.android.material.button.MaterialButton
       android:enabled="false"
       android:id="@+id/button_Join"
       style="@style/AppMaterialButton"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:text="next" 
       app:cornerRadius="0dp" />

安卓资源目录

创建颜色资源文件


0

创建启用/禁用效果的最佳方法之一是通过覆盖MaterialButton类并在其上应用ColorMatrix

import android.content.Context
import android.graphics.Canvas
import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.graphics.Paint
import android.util.AttributeSet
import com.google.android.material.button.MaterialButton

class MaterialButtonCustom @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
): MaterialButton(context,attrs,defStyleAttr) {
    var disabled = false
        set(value) {
            field = value
            requestLayout()
        }

    private val paint = Paint()

    init {
        val cm = ColorMatrix()
        cm.set(
            floatArrayOf(
                0.6f, 0.6f, 0.6f, 0f, 0f,
                0.6f, 0.6f, 0.6f, 0f, 0f,
                0.6f, 0.6f, 0.6f, 0f, 0f,
                0f, 0f, 0f, 1f, 0f
            )
        )
        paint.colorFilter = ColorMatrixColorFilter(cm)
    }

    override fun dispatchDraw(canvas: Canvas?) {
        if (disabled) {
            canvas?.saveLayer(null, paint)
        }

        super.dispatchDraw(canvas)

        if (disabled) {
            canvas?.restore()
        }
    }

    override fun draw(canvas: Canvas?) {
        if (disabled) {
            canvas?.saveLayer(null, paint)
        }

        super.draw(canvas)

        if (disabled) {
            canvas?.restore()
        }
    }
}

并且在Activity内部

class MainActivity : AppCompatActivity() {
    lateinit var btn_plus:MaterialButtonCustom
    var isActive: Boolean = false
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        btn_plus = findViewById(R.id.btn_plus)
        setBtnEnabled()
        btn_plus.setOnClickListener {
            isActive = !isActive
            if(isActive){
                setBtnDisabled()
            }else{
                setBtnEnabled()
            }
        }

    }

    private fun setBtnDisabled() {
        btn_plus.disabled = true
    }

    private fun setBtnEnabled() {
        btn_plus.disabled = false
    }
}

0
你应该使用ThemeOverlay并单独应用Colored样式。
    <style name="AccentButton" parent="ThemeOverlay.AppCompat.Dark">
         <!-- customize colorButtonNormal for the disable color -->
         <!-- customize colorAccent for the enabled color -->
    </style>

    <Button
        android:id="@+id/login_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/fragment_login_login_button"
        android:theme="@style/AccentButton"
        style="@style/Widget.AppCompat.Button.Colored"/>

0

对于那些想要在按钮禁用状态下更改图标和文本颜色的人,以下是我们可以执行的步骤,更改背景颜色的步骤几乎相同。

color/button_enable_disable_state.xml中创建一个文件。

 <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@android:color/white" android:state_enabled="true" />
    <item android:alpha=".3" android:color="@android:color/white" />
</selector>

然后进入您的主题或直接像下面这样应用于您的视图。

  <style name="ButtonStyled" parent="Widget.MaterialComponents.Button">
        <item name="iconGravity">textStart</item>
        <item name="iconPadding">12dp</item>
        <item name="iconTint">@color/button_enable_disable_state</item>
        <item name="android:textColor">@color/button_enable_disable_state</item>
    </style>

如果您使用类似以下主题的话,可以应用到您的视图中:

  <com.google.android.material.button.MaterialButton
        android:id="@+id/call_button"
        style="@style/ButtonStyled"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="20dp"
        android:layout_marginBottom="6dp"
        android:enabled="false"
        android:text="Call"
        android:visibility="visible"
        app:icon="@drawable/ic_call_icon"
       />

或者直接应用到如下视图中
 <com.google.android.material.button.MaterialButton
        android:id="@+id/call_button"
        style="@style/ButtonStyled"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="20dp"
        android:layout_marginBottom="6dp"
        android:enabled="false"
        android:text="Call"
        android:visibility="visible"
        android:textColor="@color/button_enable_disable_state"
        app:iconTint="@color/button_enable_disable_state"
        app:icon="@drawable/ic_call_icon"
        />

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