这些菜单项标题的默认样式为textAllCaps
属性设置为true
,这会导致AllCapsTransformationMethod
在标题上设置TextView
s。该转换方法在 Oreo 之前存在一个错误,即它将文本视为平面String
,这实际上会删除您可能设置的任何格式范围。
这在奥利奥中得到了纠正,但自从AllCapsTransformationMethod
是一个平台类,即使使用 support/androidx 库,该修复也不具有追溯力。对于我们自己的修复,我们可以简单地关闭textAllCaps
对于这些项目标题,并在创建格式化文本之前在代码中自行处理大小写。
对于支持/androidxActionBar
/Toolbar
,我们修改主题和样式如下:
<style name="AppTheme" parent="Theme.AppCompat...">
...
<item name="actionMenuTextAppearance">@style/TextAppearance.ActionBar.Menu.NoCaps</item>
</style>
<style name="TextAppearance.ActionBar.Menu.NoCaps"
parent="TextAppearance.AppCompat.Widget.ActionBar.Menu">
<item name="textAllCaps">false</item>
</style>
然后在代码中将标题转换为大写:
SpannableString s = new SpannableString(menuItem.getTitle().toString().toUpperCase());
对于平台来说ActionBar
/Toolbar
,我们需要在主题和样式中设置相应的平台属性。例如:
<style name="AppTheme" parent="android:Theme.Material...">
...
<item name="android:actionMenuTextAppearance">@style/TextAppearance.ActionBar.Menu.NoCaps</item>
</style>
<style name="TextAppearance.ActionBar.Menu.NoCaps"
parent="android:TextAppearance.Material.Widget.ActionBar.Menu">
<item name="android:textAllCaps">false</item>
</style>
代码更改是相同的。
由于此问题已在 Oreo 中修复,因此我们可以通过在相关中进行这些更改来仅将上述内容应用于受影响的版本res/values[-v??]/
文件夹,并使用默认设置res/values-v26/
,以及任何更高的值。
然而,为所有版本设置这种样式要简单得多,而且因为我们正在做的文本处理比现在的文本处理稍微不那么密集。AllCapsTransformationMethod
就可以了,真的没有理由不在任何地方使用它。