我正在尝试在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?
如果不需要,我不想覆盖默认值并指定不需要的任何内容。预先感谢!
答案 0 :(得分:0)
让我详细介绍一下,希望可以帮助您解决一些问题:
侧面说明:总的来说,我认为使用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"/>
对于按钮,您还可以使用默认的禁用的字母属性,例如定义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
并与{{1 }}。这些定义需要一个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
如果所有按钮都没有自定义文字颜色,则这两种状态都将使用此文字!参见Screenshot。
如果您只想修复按钮文本以更改颜色,则可以这样定义按钮样式:
<item name="android:textColorPrimary">@color/colorPrimaryTextOnLight</item>
使用<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
,如上所示。
我已经将demo project的更多屏幕截图/设置样式和主题组合上传到了Github,因为我觉得这个答案太长了,最好还是自己玩一遍,以了解样式的工作原理。
如评论中所述,我可以确认Android Studio中的预览有时会显示错误的元素,尤其是在将自定义主题应用于元素时!最好在模拟器或真实设备上进行测试。