简体   繁体   English

在不同的 Android 版本上动态更改工具栏菜单项文本颜色

[英]Change toolbar menu item text color dynamically on different Android version

Need to change toolbar menu item text color in different fragments.需要更改不同片段中的工具栏菜单项文本颜色。 Right now i have two fragments when this must work.现在我有两个片段,这必须起作用。 I set static style AppTheme with.我设置了静态样式 AppTheme。

<item name="actionMenuTextColor">@color/black</item>

In first fragment text must be black and in second white.在第一个片段文本必须是黑色的,第二个是白色的。

I used this option when set SpannableString instead of String in setTitle on menuItem.在 menuItem 的 setTitle 中设置 SpannableString 而不是 String 时,我使用了此选项。 This work good with version 8.0 and greater.这适用于 8.0 及更高版本。 When check how it works on 5.0, 6.0, 7.0 nothing change.当检查它在 5.0、6.0、7.0 上的工作方式时,没有任何变化。

Style set in Application section in AndroidManifest AndroidManifest 的 Application 部分中设置的样式

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
 <item name="colorPrimary">@color/colorPrimary</item>
 <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
 <item name="colorAccent">@color/colorAccent</item>
 <item name="actionMenuTextColor">@color/black</item>
</style>

Set in fragment > onCreateOptionsMenu method在片段中设置 > onCreateOptionsMenu 方法

MenuItem menuItem= menu.findItem(R.id.action_done);
SpannableString s = new SpannableString(menuItem.getTitle().toString());
s.setSpan(new ForegroundColorSpan(Color.WHITE), 0, s.length(), 0);
menuItem.setTitle(s);

Hope someone has idea how dynamically chnage this parameter.希望有人知道如何动态更改此参数。

The default style for those menu items' titles has the textAllCaps attribute set to true , which causes an AllCapsTransformationMethod to be set on the titles' TextView s.这些菜单项标题的默认样式将textAllCaps属性设置为true ,这会导致在标题的TextView上设置AllCapsTransformationMethod That transformation method had a bug prior to Oreo, in that it would treat the text as a flat String , which essentially strips any formatting spans that you may have set.该转换方法在 Oreo 之前有一个错误,因为它将文本视为一个平面String ,这实质上去除了您可能设置的任何格式范围。

This was corrected in Oreo, but since AllCapsTransformationMethod is a platform class, that fix isn't retroactive, even with the support/androidx libraries.这在 Oreo 中得到了纠正,但由于AllCapsTransformationMethod是一个平台类,即使使用 support/androidx 库,该修复也不具有追溯力。 For our own fix, we can simply turn off textAllCaps for those item titles, and handle the capitalization ourselves in code, before creating the formatted text.对于我们自己的修复,我们可以简单地关闭这些项目标题的textAllCaps ,并在创建格式化文本之前自己在代码中处理大写。

For the support/androidx ActionBar / Toolbar , we modify the theme and style as such:对于 support/androidx ActionBar / 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>

Then convert the title to uppercase in the code:然后将代码中的标题转换为大写:

SpannableString s = new SpannableString(menuItem.getTitle().toString().toUpperCase());

For the platform ActionBar / Toolbar , we need to set the corresponding platform attributes in the theme and style.对于平台ActionBar / Toolbar ,我们需要在主题和样式中设置相应的平台属性。 For example:例如:

<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>

The code change is the same.代码更改相同。


As this was fixed in Oreo, we could apply the above only on the affected versions by making these changes in the relevant res/values[-v??]/ folders, and using the default settings in res/values-v26/ , and any higher.由于这是在 Oreo 中修复的,我们可以通过在相关res/values[-v??]/文件夹中进行这些更改,并使用res/values-v26/的默认设置,将上述仅应用于受影响的版本,以及再高一点。

However, it is much simpler to just set this style for all versions, and since the text processing we're doing is a little less intensive than what AllCapsTransformationMethod would do, there's really no reason not to use this everywhere.然而,为所有版本设置这种样式要简单得多,而且由于我们正在做的文本处理比AllCapsTransformationMethod要少一些,所以真的没有理由不在任何地方使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM