如何在 Android 中更改菜单项的文本颜色?

Posted

技术标签:

【中文标题】如何在 Android 中更改菜单项的文本颜色?【英文标题】:How to change the Text color of Menu item in Android? 【发布时间】:2011-03-31 23:05:21 【问题描述】:

我可以更改 android 中菜单项的背景颜色吗?

如果有人对此有任何解决方案,请告诉我。最后一个选项显然是自定义它,但是有什么方法可以在不自定义的情况下更改文本颜色。

【问题讨论】:

有谁能告诉我解决办法吗? 你想改变文本颜色,文本视图的背景颜色吗?或两者?两者都是不同的东西。请重新提出问题。 【参考方案1】:

你的主题中的一个简单的行:)

<item name="android:actionMenuTextColor">@color/your_color</item>

【讨论】:

注意:这必须放在应用程序的主主题定义中,而不是在 actionBarStyle 中。它在actionBarStyle 中不起作用,尽管这看起来合乎逻辑! 要支持较低的 API 版本,请使用 &lt;item name="actionMenuTextColor"&gt;@color/your_color&lt;/item&gt; 不要使用 Android 命名空间 @ColinM。它必须进入 a 主题。如果您在工具栏上设置theme 属性,则此方法有效。 我仍然完全无法更改文本颜色。我的整体主题 textcolor 只是偏好。有什么帮助吗?这些答案都不起作用。 似乎不适用于Theme.MaterialComponents.DayNight【参考方案2】:

好像是一个

  <item name="android:itemTextAppearance">@style/myCustomMenuTextAppearance</item>

在我的主题中和

   <style name="myCustomMenuTextAppearance" parent="@android:style/TextAppearance.Widget.IconMenu.Item">
        <item name="android:textColor">@android:color/primary_text_dark</item>
    </style>

在 styles.xml 中更改列表项的样式,但不更改菜单项的样式。

【讨论】:

这适用于我一直在寻找的上下文菜单项(不是菜单按钮中的菜单项)。比整个 LayoutFactory 的混乱要简单得多。 android:itemTextAppearance 属性不能放置在其父样式为 parent="@android:style/Widget.Holo.ListPopupWindow" 的样式中,因为它不会正确呈现。它必须是***样式,例如父级为 android:Theme.Holo.Light.DarkActionBar 的样式。 我应该在哪里添加 @style/myCustomMenuTextApearance【参考方案3】:

您可以使用SpannableString 而不是String 轻松更改MenuItem 文本的颜色。

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
    inflater.inflate(R.menu.your_menu, menu);

    int positionOfMenuItem = 0; // or whatever...
    MenuItem item = menu.getItem(positionOfMenuItem);
    SpannableString s = new SpannableString("My red MenuItem");
    s.setSpan(new ForegroundColorSpan(Color.RED), 0, s.length(), 0);
    item.setTitle(s);

【讨论】:

这在 4.4 和 5+ 中都适用于我,使用 menu.findItem(R.id.menu_item_id); 而不是 menu.getItem() 也为我工作 [使用 findItem(...)]。 解决方案仅适用于溢出的项目....我不想更改通过设置 showAsAction:"always" 可见的项目颜色【参考方案4】:

如果您使用的是新的工具栏,主题为Theme.AppCompat.Light.NoActionBar,您可以通过以下方式对其进行样式设置。

 <style name="ToolbarTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:textColorPrimary">@color/my_color1</item>
    <item name="android:textColorSecondary">@color/my_color2</item>
    <item name="android:textColor">@color/my_color3</item>
 </style>`

根据我得到的结果,android:textColorPrimary 是显示活动名称的文本颜色,它是工具栏的主要文本。 android:textColorSecondary 是字幕和更多选项(3 点)按钮的文本颜色。 (是的,它根据这个属性改变了颜色!)android:textColor 是包括菜单在内的所有其他文本的颜色。 最后给Toolbar设置主题

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:theme="@style/ToolbarTheme"
    android:layout_
    android:layout_
    android:minHeight="?attr/actionBarSize"/>

【讨论】:

哪个项目控制在工具栏上显示为操作(文本)的按钮上的文本? android:textColorPrimary、android:textColorSecondary 和 android:textColor 似乎都不会影响它们。 在前面的评论中回答我的问题:android:actionMenuTextColor(见***.com/a/5538709/423105)。 直到我读到你的答案,我都快疯了,试图改变 3 个点的颜色!【参考方案5】:

我是这样以编程方式进行的:

public boolean onCreateOptionsMenu(Menu menu) 
    getMenuInflater().inflate(R.menu.changeip_card_menu, menu); 
    for(int i = 0; i < menu.size(); i++) 
        MenuItem item = menu.getItem(i);
        SpannableString spanString = new SpannableString(menu.getItem(i).getTitle().toString());
        spanString.setSpan(new ForegroundColorSpan(Color.BLACK), 0,     spanString.length(), 0); //fix the color to white
        item.setTitle(spanString);
    
    return true;

【讨论】:

您的回答帮助我将 MenuItem 文本设置为粗体。 (s.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, s.length(), 0); 谢谢! 这个解决方案帮助了我的问题。我喜欢这个,因为它不依赖于主题相关的条件。【参考方案6】:

如果您将菜单用作&lt;android.support.design.widget.NavigationView /&gt;,则只需在NavigationView 中添加以下行:

app:itemTextColor="your color"

图标也可以使用 colorTint,它也会覆盖图标的颜色。为此,您必须添加以下行:

app:itemIconTint="your color"

例子:

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_
        android:layout_
        android:layout_gravity="start"

        app:itemTextColor="@color/color_white"
        app:itemIconTint="@color/color_white"

        android:background="@color/colorPrimary"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer"/>

希望对你有所帮助。

【讨论】:

这改变了嵌套在另一个项目中的项目,但它没有改变包含其他项目的项目。你知道我也可以改变它们吗? @DinuNicolae 你能发布你的示例截图吗?或者提供更多细节。 我有 并且只有里面项目的颜色改变了【参考方案7】:

正如您在this question 中看到的那样,您应该:

<item name="android:textColorPrimary">yourColor</item>

以上代码更改 API >= v21 的菜单操作项的文本颜色。

<item name="actionMenuTextColor">@android:color/holo_green_light</item>

以上是API的代码

【讨论】:

谢谢。这应该被接受。简单易行【参考方案8】:

我在 Kotlin 中编写了这些扩展:

fun MenuItem.setTitleColor(color: Int) 
    val hexColor = Integer.toHexString(color).toUpperCase().substring(2)
    val html = "<font color='#$hexColor'>$title</font>"
    this.title = html.parseAsHtml()
           



@Suppress("DEPRECATION")                                                                        
fun String.parseAsHtml(): Spanned                                                              
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)                                 
        Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)                                         
     else                                                                                     
        Html.fromHtml(this)                                                                     
                                                                                               
  

并像这样使用:

menu.findItem(R.id.main_settings).setTitleColor(Color.RED)

【讨论】:

非常喜欢这个解决方案,非常整洁! 谢谢,简单快捷的解决方案。对于 API > 24,它可以在没有第二个 ext 函数的情况下工作【参考方案9】:

当菜单项膨胀时,我使用 html 标记更改单个项的文本颜色。希望对您有所帮助。

public boolean onCreateOptionsMenu(Menu menu) 
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    menu.findItem(R.id.main_settings).setTitle(Html.fromHtml("<font color='#ff3824'>Settings</font>"));
    return true;

【讨论】:

这对我在棉花糖上不起作用。应用文本,但不应用颜色。 关于棉花糖,可能由于 max.mustermann 的回答中所述的相同原因它不起作用,“解决方案仅适用于溢出的项目。” 此方法有效。另一种方法。 menu.getItem(position) 不起作用【参考方案10】:

为单个工具栏而不是 AppTheme 制作自定义菜单颜色的最简单方法

    <android.support.design.widget.AppBarLayout
        android:layout_
        android:layout_
        android:theme="@style/AppTheme.AppBarOverlay.MenuBlue">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_
            android:layout_/>
    </android.support.design.widget.AppBarLayout>

styles.xml 上的常用工具栏

<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>

我们的自定义工具栏样式

<style name="AppTheme.AppBarOverlay.MenuBlue">
    <item name="actionMenuTextColor">@color/blue</item>
</style>

【讨论】:

效果很好!最佳答案。【参考方案11】:

我使用的是 Material Design,当工具栏位于小屏幕上时,单击更多选项会显示一个空白的白色下拉框。为了解决这个问题,我认为将其添加到主 AppTheme:

<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="android:itemTextAppearance">@style/menuItem</item>
</style>

然后创建一个样式,将菜单项的 textColor 设置为所需的颜色。

<style name="menuItem" parent="Widget.AppCompat.TextView.SpinnerItem">
    <item name="android:textColor">@color/black</item>
</style>

父名称Widget.AppCompat.TextView.SpinnerItem 我认为这无关紧要,它应该仍然有效。

【讨论】:

因为弹出菜单就像工具栏的微调器,所以它已经将文本颜色更改为白色,同时使用工具栏中的搜索视图白色在其他屏幕上工作正常。使用上述样式后效果完美。谢谢。【参考方案12】:

使用下面的代码更改菜单项文本颜色

<style name="AppToolbar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:itemTextAppearance">@style/menu_item_color</item>
</style>

在哪里

<style name="menu_item_color">
<item name="android:textColor">@color/app_font_color</item>
</style>

【讨论】:

【参考方案13】:

简短的回答是肯定的。你很幸运! 为此,您需要覆盖 Android 默认样式的一些样式:

首先看一下Android中的definition of the themes:

<style name="Theme.IconMenu">
<!-- Menu/item attributes -->
<item name="android:itemTextAppearance">@android:style/TextAppearance.Widget.IconMenu.Item</item>
<item name="android:itemBackground">@android:drawable/menu_selector</item>
<item name="android:itemIconDisabledAlpha">?android:attr/disabledAlpha</item>
<item name="android:horizontalDivider">@android:drawable/divider_horizontal_bright</item>
<item name="android:verticalDivider">@android:drawable/divider_vertical_bright</item>
<item name="android:windowAnimationStyle">@android:style/Animation.OptionsPanel</item>
<item name="android:moreIcon">@android:drawable/ic_menu_more</item>
<item name="android:background">@null</item>
</style>

所以,菜单中文本的外观在@android:style/TextAppearance.Widget.IconMenu.Item 现在,在the styles 的定义中:

<style name="TextAppearance.Widget.IconMenu.Item" parent="TextAppearance.Small">
<item name="android:textColor">?textColorPrimaryInverse</item>
</style>

所以现在我们有了问题颜色的名称,如果你查看系统资源的颜色文件夹:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@android:color/bright_foreground_light_disabled" /> 
<item android:state_window_focused="false" android:color="@android:color/bright_foreground_light" /> 
<item android:state_pressed="true" android:color="@android:color/bright_foreground_light" /> 
<item android:state_selected="true" android:color="@android:color/bright_foreground_light" /> 
<item android:color="@android:color/bright_foreground_light" /> 
<!--  not selected --> 
</selector>

最后,这是你需要做的:

覆盖“TextAppearance.Widget.IconMenu.Item”并创建自己的样式。然后将其链接到您自己的选择器以使其成为您想要的方式。 希望这对您有所帮助。 祝你好运!

【讨论】:

感谢您的回复。我已经按照你的建议做了,但它不会改变菜单项的颜色 实际上,我通过阅读更多菜单内容才意识到它比我想象的要复杂得多如果您不想创建自己的完整自定义菜单...这将需要更多为我阅读,如果我发现更多内容,我会在此发布。 无法覆盖“TextAppearance.Widget.IconMenu.Item”。 这个答案具有误导性。所以结论是,它不起作用,而且比最初想象的更难/难以实现?【参考方案14】:

android 中的选项菜单可以自定义设置背景或更改文本外观。无法使用主题和样式更改菜单中的背景和文本颜色。 android 源代码 (data\res\layout\icon_menu_item_layout.xml) 使用“com.android.internal.view.menu.IconMenuItem”类的自定义项来进行菜单布局。我们可以在上面的类中进行修改来自定义菜单。为了达到同样的效果,请使用 LayoutInflater 工厂类并设置视图的背景和文本颜色。

@Override public boolean onCreateOptionsMenu(Menu menu) MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.my_menu, menu); getLayoutInflater().setFactory(new Factory() @Override public View onCreateView(String name, Context context, AttributeSet attrs) if (name .equalsIgnoreCase(“com.android.internal.view.menu.IconMenuItemView”)) try LayoutInflater f = getLayoutInflater(); final View view = f.createView(name, null, attrs); new Handler().post(new Runnable() public void run() // set the background drawable view .setBackgroundResource(R.drawable.my_ac_menu_background); // set the text color ((TextView) view).setTextColor(Color.WHITE); ); return view; catch (InflateException e) catch (ClassNotFoundException e) return null; ); return super.onCreateOptionsMenu(menu);

【讨论】:

03-23 19:45:25.134: E/AndroidRuntime(26761): java.lang.IllegalStateException: A factory has already been set on this LayoutInflater 这是第一次工作。当您第二次打开菜单时,您会遇到异常。【参考方案15】:

感谢代码示例。 我必须修改它才能使用上下文菜单。 这是我的解决方案。

    static final Class<?>[] constructorSignature = new Class[] Context.class, AttributeSet.class;

class MenuColorFix implements LayoutInflater.Factory 
    public View onCreateView(String name, Context context, AttributeSet attrs) 
        if (name.equalsIgnoreCase("com.android.internal.view.menu.ListMenuItemView")) 
            try 
                Class<? extends ViewGroup> clazz = context.getClassLoader().loadClass(name).asSubclass(ViewGroup.class);
                Constructor<? extends ViewGroup> constructor = clazz.getConstructor(constructorSignature);
                final ViewGroup view = constructor.newInstance(new Object[]context,attrs);

                new Handler().post(new Runnable() 
                    public void run() 
                        try 
                            view.setBackgroundColor(Color.BLACK);
                            List<View> children = getAllChildren(view);
                            for(int i = 0; i< children.size(); i++) 
                                View child = children.get(i);
                                if ( child instanceof TextView ) 
                                    ((TextView)child).setTextColor(Color.WHITE);
                                
                            
                        
                        catch (Exception e) 
                            Log.i(TAG, "Caught Exception!",e);
                        

                    
                );
                return view;
            
            catch (Exception e) 
                Log.i(TAG, "Caught Exception!",e);
            
        
        return null;
           


public List<View> getAllChildren(ViewGroup vg) 
    ArrayList<View> result = new ArrayList<View>();
    for ( int i = 0; i < vg.getChildCount(); i++ ) 
        View child = vg.getChildAt(i);
        if ( child instanceof ViewGroup) 
            result.addAll(getAllChildren((ViewGroup)child));
        
        else 
            result.add(child);
        
    
    return result;


@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) 
    LayoutInflater lInflater = getLayoutInflater();
    if ( lInflater.getFactory() == null ) 
        lInflater.setFactory(new MenuColorFix());
    
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.myMenu, menu);

对我来说,这适用于 Android 1.6、2.03 和 4.03。

【讨论】:

如果您正在执行上述操作,那么您应该只考虑使用 Marcus Wolschon 解决方案。简单得多。 xml 解决方案不适用于我,例如2.3.x,但这就像一个魅力 - 也在 4.x 这个解决方案效果最好。我还必须捕获 android.support.v7.internal.view.menu.ListMenuItemView 以使用兼容性库在设备上应用样式 此修复不适用于 Google Maps v2 - 必须首先调用 super 方法才能正确呈现地图。【参考方案16】:

我发现它尤里卡!!

在您的应用主题中:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:actionBarStyle">@style/ActionBarTheme</item>
    <!-- backward compatibility -->          
    <item name="actionBarStyle">@style/ActionBarTheme</item>        
</style>

这是您的操作栏主题:

<style name="ActionBarTheme" parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
   <item name="android:background">@color/actionbar_bg_color</item>
   <item name="popupTheme">@style/ActionBarPopupTheme</item
   <!-- backward compatibility -->
   <item name="background">@color/actionbar_bg_color</item>
</style>

这是您的弹出主题:

 <style name="ActionBarPopupTheme">
    <item name="android:textColor">@color/menu_text_color</item>
    <item name="android:background">@color/menu_bg_color</item>
 </style>

干杯 ;)

【讨论】:

【参考方案17】:

感谢 max.musterman,这是我在第 22 级时得到的解决方案:

public boolean onCreateOptionsMenu(Menu menu) 
    getMenuInflater().inflate(R.menu.menu_main, menu);
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    MenuItem searchMenuItem = menu.findItem(R.id.search);
    SearchView searchView = (SearchView) searchMenuItem.getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setSubmitButtonEnabled(true);
    searchView.setOnQueryTextListener(this);
    setMenuTextColor(menu, R.id.displaySummary, R.string.show_summary);
    setMenuTextColor(menu, R.id.about, R.string.text_about);
    setMenuTextColor(menu, R.id.importExport, R.string.import_export);
    setMenuTextColor(menu, R.id.preferences, R.string.settings);
    return true;


private void setMenuTextColor(Menu menu, int menuResource, int menuTextResource) 
    MenuItem item = menu.findItem(menuResource);
    SpannableString s = new SpannableString(getString(menuTextResource));
    s.setSpan(new ForegroundColorSpan(Color.BLACK), 0, s.length(), 0);
    item.setTitle(s);

硬编码的Color.BLACK 可以成为setMenuTextColor 方法的附加参数。另外,我只将它用于android:showAsAction="never" 的菜单项。

【讨论】:

在 API 24 上不适合我。有什么想法吗?被困在这几天......荒谬! 不知道该告诉你什么。这在 API 25 中对我来说很好用。【参考方案18】:

只需将此添加到您的主题中

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:itemTextAppearance">@style/AppTheme.ItemTextStyle</item>
</style>

<style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget.IconMenu.Item">
        <item name="android:textColor">@color/orange_500</item>
</style>

在 API 21 上测试

【讨论】:

最好使用&lt;style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget"&gt;,否则溢出菜单中的文字显得太小。另请注意,此技术仅适用于 Android 5 及更高版本。【参考方案19】:

您可以通过编程方式设置颜色。

private static void setMenuTextColor(final Context context, final Toolbar toolbar, final int menuResId, final int colorRes) 
    toolbar.post(new Runnable() 
        @Override
        public void run() 
            View settingsMenuItem =  toolbar.findViewById(menuResId);
            if (settingsMenuItem instanceof TextView) 
                if (DEBUG) 
                    Log.i(TAG, "setMenuTextColor textview");
                
                TextView tv = (TextView) settingsMenuItem;
                tv.setTextColor(ContextCompat.getColor(context, colorRes));
             else  // you can ignore this branch, because usually there is not the situation
                Menu menu = toolbar.getMenu();
                MenuItem item = menu.findItem(menuResId);
                SpannableString s = new SpannableString(item.getTitle());
                s.setSpan(new ForegroundColorSpan(ContextCompat.getColor(context, colorRes)), 0, s.length(), 0);
                item.setTitle(s);
            

        
    );

【讨论】:

【参考方案20】:

将其添加到我的 styles.xml 中对我有用

<item name="android:textColorPrimary">?android:attr/textColorPrimaryInverse</item>

【讨论】:

【参考方案21】:

如果您想为单个菜单项设置颜色,自定义工具栏主题不是正确的解决方案。为此,您可以使用 android:actionLayout 和菜单项的操作视图。

首先为动作视图创建一个 XML 布局文件。在这个例子中,我们使用一个按钮作为一个动作视图:

menu_button.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:layout_>

    <Button
        android:id="@+id/menuButton"
        android:layout_
        android:layout_
        android:text="Done"
        android:textColor="?android:attr/colorAccent"
        style="?android:attr/buttonBarButtonStyle"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

在上面的代码sn-p中,我们使用android:textColor="?android:attr/colorAccent"来自定义按钮文字颜色。

然后在菜单的 XML 布局文件中,包括 app:actionLayout="@layout/menu_button",如下所示:

main_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/menuItem"
        android:title=""
        app:actionLayout="@layout/menu_button"
        app:showAsAction="always"/>
</menu>

最后在你的活动中覆盖onCreateOptionsMenu() 方法:

@Override
public boolean onCreateOptionsMenu(Menu menu) 
    getMenuInflater().inflate(R.menu.main_menu, menu);
    MenuItem item = menu.findItem(R.id.menuItem);
    Button saveButton = item.getActionView().findViewById(R.id.menuButton);
    saveButton.setOnClickListener(view -> 
        // Do something
    );
    return true;

...或片段:

@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater)
    inflater.inflate(R.menu.main_menu, menu);
    MenuItem item = menu.findItem(R.id.menuItem);
    Button saveButton = item.getActionView().findViewById(R.id.menuButton);
    button.setOnClickListener(view -> 
        // Do something
    );

有关操作视图的更多详细信息,请参阅Android developer guide。

【讨论】:

【参考方案22】:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
    inflater.inflate(R.menu.search, menu);


    MenuItem myActionMenuItem = menu.findItem( R.id.action_search);
    SearchView searchView = (SearchView) myActionMenuItem.getActionView();

    EditText searchEditText = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
    searchEditText.setTextColor(Color.WHITE); //You color here

【讨论】:

解释你的答案 如果不是 SearchView 怎么办?【参考方案23】:

我的情况是在选项菜单中设置文本颜色(按下菜单按钮时显示主应用菜单)。

API 16 中使用 appcompat-v7-27.0.2 库进行测试,AppCompatActivity 用于 MainActivityAppCompat 主题用于 中的应用程序AndroidManifest.xml.

styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  <item name="actionBarPopupTheme">@style/PopupTheme</item>
</style>

<style name="PopupTheme" parent="@style/ThemeOverlay.AppCompat.Light">
  <item name="android:textColorSecondary">#f00</item>
</style>

不知道textColorSecondary 是否影响其他元素,但它控制菜单文本颜色。


我搜索了一些关于该主题的示例,但所有现成的 sn-ps 都不起作用。

所以我想用 appcompat-v7 库的源代码(特别是 .aarres 文件夹来研究它包)。

虽然在我的例子中,我使用了带有爆炸 .aar 依赖关系的 Eclipse。所以我可以更改默认样式并检查结果。不知道如何分解库以直接与 GradleAndroid Studio 一起使用。它值得另一个调查。

所以我的目的是找出 res/values/values.xml 文件中的哪种颜色用于菜单文本(我几乎可以确定颜色存在)。

    我打开了该文件,然后复制了所有颜色,将它们置于默认颜色之下以覆盖它们,并为所有颜色分配了 #f00 值。 启动应用程序。 许多元素具有红色背景或文本颜色。还有菜单项。这正是我所需要的。 以 5-10 行的块删除我添加的颜色,最后以 secondary_text_default_material_light 颜色项结束。 在 res 文件夹中的文件中搜索该名称(或者在 res/colors 中更好),我在 color/abc_secondary_text_material_light.xml 中只发现了一次 文件(我使用 Sublime Text 进行这些操作,因此更容易找到我需要的东西)。 返回 values.xml 发现 @color/abc_secondary_text_material_light 的 8 个用法。 这是一个Light主题,所以在 2 个主题中剩下 4 个:Base.ThemeOverlay.AppCompat.LightPlatform.AppCompat.Light。 第一个主题是第二个主题的子主题,因此该颜色资源只有 2 个属性:android:textColorSecondaryandroid:textColorTertiaryBase.ThemeOverlay.AppCompat.Light。 直接在values.xml中更改它们的值并运行应用程序我发现最终正确的属性是android:textColorSecondary。 接下来我需要一个主题或其他属性,以便我可以在我的应用的 style.xml 中更改它(因为我的主题的父主题是 Theme.AppCompat.Light 而不是 ThemeOverlay.AppCompat.Light)。 我在同一个文件中搜索了Base.ThemeOverlay.AppCompat.Light。它有一个孩子ThemeOverlay.AppCompat.Light。 搜索ThemeOverlay.AppCompat.Light 我发现它在Base.Theme.AppCompat.Light.DarkActionBar 主题中用作actionBarPopupTheme 属性值。 我的应用主题 Theme.AppCompat.Light.DarkActionBar 是找到的 Base.Theme.AppCompat.Light.DarkActionBar 的子主题,因此我可以毫无问题地在 styles.xml 中使用该属性。 从上面的示例代码中可以看出,我从提到的ThemeOverlay.AppCompat.Light 创建了一个子主题并更改了android:textColorSecondary 属性。

【讨论】:

【参考方案24】:

Sephy's solution 不起作用。可以使用上述方法覆盖选项菜单项文本外观,但不能覆盖项目或菜单。要做到这一点,基本上有 3 种方法:

    How to change the background color of the options menu? 编写您自己的视图来显示和覆盖 onCreateOptionsMenu 和 onPrepareOptionsMenu 以获得您想要的结果。我之所以这么说,是因为您通常可以在这些方法中做任何您想做的事情,但您可能不想调用 super()。 从开源 SDK 复制代码并根据您的行为进行自定义。 Activity 使用的默认菜单实现将不再适用。

更多线索请见Issue 4441: Custom Options Menu Theme。

【讨论】:

重申...Sephy 的解决方案适用于菜单项TextAppearance,尽管我所做的是通过themes.xml 覆盖默认值。此外,上面的#2 或#3 应该知道调用 super#onCreateOptionsMenu/super#onPrepareOptionsMenu 旨在放置系统菜单项...如 Activity#onCreateOptionsMenu() 的 javadoc 中所示。这对您的应用可能/可能无关紧要。 Sephy 描述的是在你的themes.xml 中有这个:@style/Text_MenuItemText 然后在你的styles.xml 中定义这样的东西: 就这么简单.那是你的意思吗?更深层次的选项菜单定制一点都不容易,但我打算很快发表一篇关于它的博客文章。【参考方案25】:

试试这个代码....

 @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.my_menu, menu);

        getLayoutInflater().setFactory(new Factory() 
            @Override
            public View onCreateView(String name, Context context,
                    AttributeSet attrs) 

                if (name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView")) 
                    try 
                        LayoutInflater f = getLayoutInflater();
                        final View view = f.createView(name, null, attrs);

                        new Handler().post(new Runnable() 
                            public void run() 

                                // set the background drawable
                                 view.setBackgroundResource(R.drawable.my_ac_menu_background);

                                // set the text color
                                ((TextView) view).setTextColor(Color.WHITE);
                            
                        );
                        return view;
                     catch (InflateException e) 
                     catch (ClassNotFoundException e) 
                    
                
                return null;
            
        );
        return super.onCreateOptionsMenu(menu);
    

【讨论】:

在 Android > 4.0 我得到java.lang.IllegalStateException: A factory has already been set on this LayoutInflater【参考方案26】:

这是您可以使用颜色为特定菜单项着色的方法,适用于所有 API 级别:

public static void setToolbarMenuItemTextColor(final Toolbar toolbar,
                                               final @ColorRes int color,
                                               @IdRes final int resId) 
    if (toolbar != null) 
        for (int i = 0; i < toolbar.getChildCount(); i++) 
            final View view = toolbar.getChildAt(i);
            if (view instanceof ActionMenuView) 
                final ActionMenuView actionMenuView = (ActionMenuView) view;
                // view children are accessible only after layout-ing
                actionMenuView.post(new Runnable() 
                    @Override
                    public void run() 
                        for (int j = 0; j < actionMenuView.getChildCount(); j++) 
                            final View innerView = actionMenuView.getChildAt(j);
                            if (innerView instanceof ActionMenuItemView) 
                                final ActionMenuItemView itemView = (ActionMenuItemView) innerView;
                                if (resId == itemView.getId()) 
                                    itemView.setTextColor(ContextCompat.getColor(toolbar.getContext(), color));
                                
                            
                        
                    
                );
            
        
    

这样做你会失去背景选择器的效果,所以这里是将自定义背景选择器应用到所有子菜单项的代码。

public static void setToolbarMenuItemsBackgroundSelector(final Context context,
                                                         final Toolbar toolbar) 
    if (toolbar != null) 
        for (int i = 0; i < toolbar.getChildCount(); i++) 
            final View view = toolbar.getChildAt(i);
            if (view instanceof ImageButton) 
                // left toolbar icon (navigation, hamburger, ...)
                UiHelper.setViewBackgroundSelector(context, view);
             else if (view instanceof ActionMenuView) 
                final ActionMenuView actionMenuView = (ActionMenuView) view;

                // view children are accessible only after layout-ing
                actionMenuView.post(new Runnable() 
                    @Override
                    public void run() 
                        for (int j = 0; j < actionMenuView.getChildCount(); j++) 
                            final View innerView = actionMenuView.getChildAt(j);
                            if (innerView instanceof ActionMenuItemView) 
                                // text item views
                                final ActionMenuItemView itemView = (ActionMenuItemView) innerView;
                                UiHelper.setViewBackgroundSelector(context, itemView);

                                // icon item views
                                for (int k = 0; k < itemView.getCompoundDrawables().length; k++) 
                                    if (itemView.getCompoundDrawables()[k] != null) 
                                        UiHelper.setViewBackgroundSelector(context, itemView);
                                    
                                
                            
                        
                    
                );
            
        
    

这里也是辅助函数:

public static void setViewBackgroundSelector(@NonNull Context context, @NonNull View itemView) 
    int[] attrs = new int[]R.attr.selectableItemBackgroundBorderless;
    TypedArray ta = context.obtainStyledAttributes(attrs);
    Drawable drawable = ta.getDrawable(0);
    ta.recycle();

    ViewCompat.setBackground(itemView, drawable);

【讨论】:

【参考方案27】:

要更改文本颜色,您可以为 MenuItem 设置自定义视图,然后您可以定义文本的颜色。

示例代码:MenuItem.setActionView()

【讨论】:

虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。【参考方案28】:

如下添加textColor

<style name="MyTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light">
    <item name="android:textColor">@color/radio_color_gray</item>
</style>

并在 xml 文件的工具栏中使用它

<androidx.appcompat.widget.Toolbar
     android:id="@+id/toolbar"
     android:layout_
     android:layout_
     app:popupTheme="@style/MyTheme.PopupOverlay" /> 

【讨论】:

【参考方案29】:

只需转到 值 - 样式和内部样式和类型 你的颜色

【讨论】:

以上是关于如何在 Android 中更改菜单项的文本颜色?的主要内容,如果未能解决你的问题,请参考以下文章

更改导航抽屉中菜单项的文本颜色

如何动态更改网页所选菜单项的颜色?

将鼠标悬停在上下文菜单上时如何更改 li 项的颜色

更改 navigationView 的单个特定菜单项的背景颜色

如何更改第一个选择选项的文本颜色

如何在 Android 中动态更改菜单项文本