我正在尝试在setEnabled(false)
上使用Button
来显示灰色的禁用状态...
如果我强制按钮上的主题,我只能得到想要的结果
android:theme="@style/Button"
然后将该Button样式的父级更改为
Theme.AppCompat.Light.DarkActionBar
以外的其他名称,例如从Material:<style name="Button" parent="android:Theme.Material.Light.NoActionBar">
(即使那样,仅按钮背景也会更改,文本颜色不会更改。)
如果我将按钮保留为默认值,则在设置为禁用时,我不会看到该按钮为灰色。 (我的理解是,使用
Theme.AppCompat.
时,Button
变为AppCompat.Widget.Button
并继承了ColorStateList
。)在我的
res\values\styles.xml
中 <resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<!-- only way I could get this to work -->
<style name="Button" parent="android:Theme.Material.Light.NoActionBar">
<!--<item name="colorAccent">@color/butt</item>-->
<!--<item name="colorButtonNormal">@color/butt</item>-->
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>
在
AndroidManifest.xml
中 <application
android:theme="@style/AppTheme"
( and nothing under <activity> )
我的
MainActivity
扩展了Activity
但是我也尝试了扩展
AppCompatActivity
并遇到了同样的问题。那么这是怎么回事?为什么默认功能不适用于“禁用的按钮”?
(如果我确实继承了
Material
主题(如上所述),为什么Button文本的颜色不会改变?基本上,为什么Button看起来不像它们在主题编辑器中一样?)也
当我通过
ColorStateList
指定自定义res\color
时,为什么不能仅覆盖某些状态?我试图只有<item android:state_enabled="false" android:color="#616161" />
但这没有用。如果我指定了更多的
<item>
,即使我不在乎匹配其他状态,我也只能使用此方法获得灰色的禁用按钮。仅当我添加类似内容时它才有效:<!-- disabled state -->
<item android:state_enabled="false" android:color="#616161" />
<!-- enabled state -->
<item android:state_enabled="true" android:color="@color/colorPrimaryLighter" />
<!-- default -->
<item android:color="#ffffff"/>
我的
supportLibraryVersion = '27.1.1'
我已经看过
How to setup disabled color of button with AppCompat?
Widget.AppCompat.Button colorButtonNormal shows gray
State list drawable and disabled state
Android - default button style
Android: change color of disabled text using Theme/Style?
When should one use Theme.AppCompat vs ThemeOverlay.AppCompat?
Use android:theme and ThemeOverlay to theme specific Views and their descendents Pro-tip by +Ian Lake
和
Nesting Android Themes
我不想覆盖默认值,如果我不必指定不需要的任何内容。提前致谢!
最佳答案
让我详细介绍,希望能帮助您解决一些问题:
激活默认材质按钮:
旁注:总的来说,我认为使用AppCompat主题同时使用AppCompatActivity
等时,可以使外观和行为更加一致。
但是,正如您仅通过使用AppCompat
主题所注意到的那样,Button
(内部映射到android.support.v7.widget.AppCompatButton
)不会自动应用兼容性材料样式。
我不确定这是否是错误,但我怀疑这是为了保持向后兼容。您可以通过直接在视图上应用正确的样式来轻松激活它:
<Button
style="@style/Widget.AppCompat.Button.Colored"
... />
这是一个截图,显示了启用和禁用按钮的不同外观。
样式按钮是前两个。活动对象具有粉红色的重音颜色作为背景。
旧的Android按钮是底部的两个。如您所见,禁用仅会更改文本颜色和略微的轮廓。
如果要将其应用于您在应用程序中使用的任何按钮,则可以将以下行添加到您的
AppTheme
中:<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="buttonStyle">@style/Widget.AppCompat.Button.Colored</item>
...
这将使用默认的colorAccent作为按钮突出显示颜色,并使用灰色调作为禁用的平面按钮。您提到仅在清单中为
android:theme
定义App
。为了使该解决方案起作用,您可能需要将主题设置为每个Activity
。定义不同状态的颜色
ColorStateList
的想法是定义根据View
状态变化的颜色。如果特定定义的条件不匹配,则需要使用默认情况作为后备。您的示例可以简化为以下内容:
<!-- disabled state -->
<item android:state_enabled="false" android:color="#616161" />
<!-- default = enabled state -->
<item android:color="@color/colorPrimaryLighter"/>
对于按钮,您还可以使用默认的禁用alpha属性,例如定义
button_accent_stated
=<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:alpha="?android:attr/disabledAlpha"
android:color="@color/colorAccent"/>
<item android:color="@color/colorAccent" />
</selector>
自定义颜色样式
如果您对默认设置感到满意,则可以忽略以下部分...
如果要设置按钮的样式(其他组件也是如此)并为其指定自定义颜色,则需要在应用样式和主题之间进行区别。两者都在
styles.xml
中定义,因此可能造成混淆。我可以建议给定义起一个代表它们如何使用的名称。例如,当您要覆盖强调色时,可以创建自定义
ButtonTheme
并使用android:theme
对其进行应用,如问题所示。当您想要调整组件的外观时(例如使用材质按钮来获得不同的禁用颜色),您可以创建自定义
ButtonStyle
并使用style
对其进行应用。这些定义需要与parent
对应的View
。使用材料按钮和最新的支持库,以前使用
colorButtonNormal
设置禁用颜色的方法似乎不再起作用。相反,您可以通过创建自定义样式并将其设置为backgroundTint
来使用上一步中定义的颜色。<style name="AppTheme.ButtonStyle" parent="@style/Widget.AppCompat.Button.Colored">
<item name="colorAccent">@color/colorAccent</item>
<item name="android:backgroundTint">@color/button_accent_stated</item>
</style>
这将导致如下所示的禁用按钮:
同样,您可以按每个按钮或整体在
AppTheme
中应用此样式。如果仍然需要支持棒棒糖之前的设备,则可能还需要一个自定义主题来设置colorButtonNormal
。更新:默认材料+指定的文字颜色:
玩我的示例应用程序后,我发现阻止默认规定的文字颜色的唯一其他解释是在您的
android:textColorPrimary
上定义了AppTheme
!<item name="android:textColorPrimary">@color/colorPrimaryTextOnLight</item>
如果您拥有所有这些按钮,但没有自定义文本颜色,则这两种状态都将使用此文本!请参见Screenshot。
如果您只想修复按钮文本以更改颜色,则可以这样定义按钮样式:
<style name="AppTheme.TextStatedButtonStyle" parent="@style/Widget.AppCompat.Button.Colored">
<item name="android:textColor">@color/button_text_stated</item>
</style>
使用
button_text_stated
这样的选择器:<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:alpha="?android:disabledAlpha"
android:color="@color/colorPrimaryTextOnLight" />
<item android:color="@color/colorPrimaryTextOnDark" />
</selector>
只需将
buttonStyle
应用于所有按钮,或将每个按钮用作style
,如上所示。我已经将我的demo project和更多的屏幕截图/设置样式和主题组合上传到了Github,因为我觉得这个答案太长了,最好还是随便玩一下,以了解样式的工作原理。
在Android Studio中预览
如评论中所述,我可以确认Android Studio中的预览有时会显示错误的元素,尤其是在将自定义主题应用于元素时!最好在仿真器或真实设备上进行测试。
关于android - 为什么setEnabled(false)不会触发主题Theme.AppCompat.Light的ColorStateList?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53071828/