【问题标题】:How do I set the disabled color of a button with AppCompat?如何使用 AppCompat 设置按钮的禁用颜色?
【发布时间】:2016-06-19 01:08:59
【问题描述】:

我用这个样式来改变我Button的背景颜色:

<style name="AccentButton" parent="Widget.AppCompat.Button.Colored">
    <item name="colorButtonNormal">@color/colorAccent</item>
    <item name="android:textColor">@color/white</item>
</style>

在布局中:

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

它有效。但是当我在这个Button 上调用setEnabled(false) 时,它保持相同的颜色。我该如何处理这种情况?

【问题讨论】:

    标签: android android-appcompat android-button


    【解决方案1】:

    您应该使用带有选择器的背景,而不是为您的按钮使用颜色。这是演示代码

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_enabled="true">
            <shape android:shape="rectangle">
                <solid android:color="@color/yourEnabledColor" />
            </shape>
        </item>
        <item android:state_enabled="false">
            <shape android:shape="rectangle">
                <solid android:color="@color/yourDisabledColor" />
            </shape>
        </item>
    </selector>
    

    【讨论】:

    • 当您绘制的不是通常的矩形按钮时,这是一个很好的建议。
    • 这是否与 api >= 16 和
    【解决方案2】:

    当您以编程方式进行更改时,您需要这样做:

    button = new Button(new ContextThemeWrapper(ActiVityName.this, R.style.AccentButton));
    

    if (button.isEnabled())
        button.getBackground().setColorFilter(Color.Black, PorterDuff.Mode.MULTIPLY);
    else
        button.getBackground().setColorFilter(null);
    

    【讨论】:

      【解决方案3】:

      您没有正确使用Widget.AppCompat.Button.Colored 样式。您正在使用父样式 (Widget.AppCompat.Button.Colored),但将其应用为主题。这实际上意味着 Widget.AppCompat.Button.Colored 部分被完全忽略,而您只是更改按钮的默认颜色(有效,但不处理禁用的情况)。

      相反,您应该使用 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"/>
      

      this answer on using the Widget.AppCompat.Button.Colored style 中所述,禁用颜色由colorButtonNormal 控制,启用颜色由colorAccent 控制。通过使用ThemeOverlay.AppCompat.DarktextColor 会自动变为深色,这意味着您可能根本不需要自定义的ThemeOverlay

      【讨论】:

      • 自定义ThemeOverlay.AppCompat.Light 命名为AccentButton 对我来说是最清晰的方法。只有一个colorButtonNormal,当Button 被禁用时,它看起来就像accentColor 与白色混合。谢谢!
      • 不是单独应用 Colored 样式,一种简化是将此样式声明移动到 AccentButton 主题中:将其定义为主题的 buttonStyle。这样,每个按钮声明只需添加一个附加属性。
      • @JoeBowbeer - 正如Choosing a Button Style blog post 中提到的,凸起的彩色按钮不一定是整个主题的常态,因此将其设置为您的基础buttonTheme 可能有点多。
      • 使用 ThemeOverlay.AppCompat.Dark (或 Light)是正确的方法,因为它也可以在 Android Studio 的设计器中正确呈现,但是设置强调色不起作用,并且 colorButtonNormal 应该是启用颜色。
      • 有没有人注意到当我们应用彩色样式时“涟漪效应”消失了?
      【解决方案4】:

      将接受的解决方案与自定义小部件相结合,我们可以通过设置 alpha 来创建一个显示为禁用的按钮。这应该适用于任何按钮和文本颜色组合:

      public class ButtonWidget extends AppCompatButton {
      
          public ButtonWidget(Context context) {
              super(context);
          }
      
          public ButtonWidget(Context context, AttributeSet attrs) {
              super(context, attrs);
          }
      
          public ButtonWidget(Context context, AttributeSet attrs, int defStyleAttr) {
              super(context, attrs, defStyleAttr);
          }
      
          @Override
          public void setEnabled(boolean enabled) {
              setAlpha(enabled ? 1 : 0.5f);
              super.setEnabled(enabled);
          }
      
      }
      

      【讨论】:

      • 设置 alpha 是要走的路。
      • 这很好用,我赞成这个答案,并在下面提供了我的 Kotlin 实现,以防它对任何人有帮助。
      • 这是一个很好的解决方案,但是,如果按钮在 xml 中默认为 android:enabled="false",我们可能需要在构造函数中添加一些逻辑来处理它。因为我们可以为启用/禁用按钮设置自定义背景。默认情况下,xml 中的 android:enabled="false" 将显示默认禁用背景,而不是自定义禁用按钮背景。
      【解决方案5】:

      目前,我对 Android API 15+ 使用以下设置。

      /res/color/btn_text_color.xml

      <?xml version="1.0" encoding="utf-8"?>
      <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:color="#42000000" android:state_enabled="false" />
        <item android:color="#ffffff" />
      </selector>
      

      /res/values/styles.xml

      <style name="ColoredButton" parent="Widget.AppCompat.Button.Colored">
          <item name="android:textColor">@color/btn_text_color</item>
      </style>
      

      <Button
          android:id="@+id/button"
          style="@style/ColoredButton"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="button" />
      

      【讨论】:

      • 嗨,我知道这个答案很老了,但我让你失望了,我有:Caused by: android.content.res.Resources$NotFoundException: File res/color/color_background_button_primary2.xml from drawable resource ID #0x7f060030 (...) Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #3: &lt;item&gt; tag requires a 'drawable' attribute or child tag defining a drawable
      【解决方案6】:

      完整的解决方案延伸自ianhanniballake'的回答和Joe Bowbeer'的评论:

      /res/values/styles.xml

      <style name="AccentButton" parent="ThemeOverlay.AppCompat.Dark">
          <!-- customize colorAccent for the enabled color -->
          <!-- customize colorControlHighlight for the enabled/pressed color -->
          <!-- customize colorButtonNormal for the disabled color -->
          <item name="android:buttonStyle">@style/Widget.AppCompat.Button.Colored</item>
      </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"/>
      

      这对我来说真的很棒

      【讨论】:

        【解决方案7】:

        上面@meanman 答案的 Kotlin 实现,调整 alpha 是迄今为止最简单的方法,我所有的触摸涟漪效果仍然像以前一样工作:

        import android.content.Context
        import android.support.v7.widget.AppCompatButton
        import android.util.AttributeSet
        
        class FadedDisableButton : AppCompatButton {
            constructor(context: Context) : super(context)
            constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
            constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
        
            override fun setEnabled(enabled: Boolean) {
                alpha = when {
                    enabled -> 1.0f
                    else -> 0.5f
                }
                super.setEnabled(enabled)
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-09-28
          • 2019-07-20
          • 2023-01-25
          • 1970-01-01
          • 2013-08-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多