Как изменить цвет текста элемента меню в Android?

175

Можно ли изменить цвет фона элемента меню в Android?

Пожалуйста, дайте мне знать, если у кого-нибудь есть решение для этого. Последний вариант, очевидно, будет настраивать его, но есть ли способ изменить цвет текста без его настройки.

Сунил
источник
Есть ли кто-нибудь, кто может дать мне знать решение этой проблемы?
Сунил
3
Вы хотите изменить цвет текста, цвет фона текстового представления? или оба? Оба разные вещи. Пожалуйста, переформулируйте вопрос.
Абхинав Саксена

Ответы:

335

Одна простая строчка в вашей теме :)

<item name="android:actionMenuTextColor">@color/your_color</item>
Мухаммед Альфаифи
источник
19
ПРИМЕЧАНИЕ. Это ДОЛЖНО быть в основном определении темы для вашего приложения, а НЕ в пределах, actionBarStyleнапример. Это не будет работать внутри actionBarStyle, даже если это кажется логичным!
Колин М.
47
Для поддержки более низких версий API используйте <item name="actionMenuTextColor">@color/your_color</item>не используйте пространство имен Android
alex.p
5
@ColinM. Он должен идти в виде темы. Если вы установите themeатрибут на панели инструментов, это работает.
DariusL
2
Не работал для меня ни с или без Android: пространство имен. Он был добавлен в основную тему приложения.
racs
2
Я все еще не могу изменить цвет текста. Моя общая тема textcolor просто берет предпочтение. Любая помощь? Ни один из этих ответов не работает.
Дэвид П
115

Кажется, что

  <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 изменить стиль элементов списка, но не пунктов меню.

Маркус Волчон
источник
5
Это прекрасно работает для пунктов контекстного меню (не пунктов меню от кнопки меню), что я и искал. Гораздо проще, чем весь беспорядок в LayoutFactory.
chubbsondubs
android:itemTextAppearanceАтрибут не может быть помещен в стиле , чей родитель , parent="@android:style/Widget.Holo.ListPopupWindow"так что не будет отображаться корректно. Он должен быть в стиле верхнего уровня, как тот, чей родитель android:Theme.Holo.Light.DarkActionBar.
toobsco42
Куда мне добавить <item name = "android: itemTextAppearance"> @ style / myCustomMenuTextApearance </ item>?
Bagusflyer
@bagusflyer следует добавить , что в корневом стиле вашей темы, то есть стиль , который является потомком Theme.Holoили Theme.Holo.Light.DarkActionBarили аналогичный.
Таш Пемхива
86

Вы можете легко изменить цвет MenuItemтекста, используя SpannableStringвместо String.

@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);
}
max.mustermann
источник
10
Это работало для меня как в 4.4, так и в 5+, используя menu.findItem(R.id.menu_item_id);вместоmenu.getItem()
haagmm
1
У меня тоже сработало [используя findItem (...)].
ошеломлен
6
Решения работают только для элемента в переполнении .... Я не хочу менять цвет элемента, который отображается, устанавливая showAsAction: "always"
Junaid
56

Если вы используете новую панель инструментов с темой 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- цвет для всего другого текста, включая меню.

Наконец, установите тему на панель инструментов

<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_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"/>
Sudara
источник
Какой элемент управляет текстом на кнопках, которые отображаются как действия (текст) на панели инструментов? Ни android: textColorPrimary, android: textColorSecondary, ни android: textColor не влияют на них.
LarsH
В ответ на мой вопрос в предыдущем комментарии: android:actionMenuTextColor(см. Stackoverflow.com/a/5538709/423105 ).
LarsH
32

Если вы используете меню как, <android.support.design.widget.NavigationView />то просто добавьте строку ниже NavigationView:

app:itemTextColor="your color"

Также доступен colorTint для значка, он также переопределит цвет для вашего значка. Для этого вы должны добавить строку ниже:

app:itemIconTint="your color"

Пример:

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        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 Можете ли вы опубликовать пример экрана? Или предоставьте больше деталей.
Михир Триведи
У меня было <item> <menu> <inside items> </ menu> </ item> и менялся только цвет предметов внутри
Dinu Nicolae
31

Я сделал это программно так:

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;
}
Мураликришна Г.С.
источник
2
Ваш ответ помог мне выделить текст MenuItem жирным шрифтом. (s.setSpan (новый StyleSpan (android.graphics.Typeface.BOLD), 0, s.length (), 0); Спасибо!
Аркадиуш Цежлинский
Это решение помогло моей проблеме. Мне нравится это, так как это не будет зависеть от тематических условий.
Tomcat
15

как вы можете видеть в этом вопросе, вы должны:

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

Код выше меняет цвет текста пунктов действий меню для API> = v21.

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

Выше приведен код для API <v21

Поуя Данеш
источник
Спасибо. Это должно быть принято. Это просто и легко
Пуджа
10

Я использовал 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;
}
alijandro
источник
1
Это не работает для меня на Зефир. Текст применяется, но не цвет.
Олли С
Что касается Зефира, возможно, он не работает по той же причине, которая указана в ответе max.mustermann: «решения работают только для переполненных элементов».
Jose_GD
10

ПРОСТОЙ способ сделать пользовательский цвет меню для одной панели инструментов, а не для AppTheme

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay.MenuBlue">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"/>
    </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>
Andrews
источник
Прекрасно работает! Лучший ответ.
bebe
9

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

Краткий ответ: да. повезло тебе!
Для этого вам нужно переопределить некоторые стили стилей Android по умолчанию:

Сначала посмотрите на определение тем в Android:

<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
сейчас, в определении стилей :

<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» и создайте свой собственный стиль. Затем свяжите его с вашим собственным селектором, чтобы сделать его так, как вы хотите. Надеюсь, это поможет вам. Удачи!

Sephy
источник
Спасибо за ответ. Я сделал то, что вы предложили, но это не изменило цвет пункта меню
Sunil
На самом деле, я только что понял, прочитав больше пунктов меню, что это намного сложнее, чем я думал. Если вы не хотите создавать свое собственное полное пользовательское меню ... Вы разместили здесь, если я найду больше.
Сефи
Невозможно переопределить «TextAppearance.Widget.IconMenu.Item».
peceps
Этот ответ вводит в заблуждение ... поэтому вывод таков: он не работает и его гораздо труднее / затягивать, чем первоначально предполагалось?
speedynomads
6

Меню параметров в Android можно настроить, чтобы установить фон или изменить внешний вид текста. Фон и цвет текста в меню не могут быть изменены с помощью тем и стилей. Исходный код Android (data \ res \ layout \ icon_menu_item_layout.xml) использует пользовательский элемент класса «com.android.internal.view.menu.IconMenuItem» View для макета меню. Мы можем внести изменения в вышеупомянутый класс, чтобы настроить меню. Чтобы добиться того же, используйте фабричный класс 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);
}


Абхай Кумар
источник
3
03-23 19:45:25.134: E/AndroidRuntime(26761): java.lang.IllegalStateException: A factory has already been set on this LayoutInflater
К кра
Это работает впервые. Когда вы открываете меню во второй раз, вы получаете исключение.
LoveForDroid
6

Спасибо за пример кода. Мне пришлось изменить его, чтобы заставить его работать с контекстным меню. Это моё решение.

    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. Гораздо проще
chubbsondubs
Решение xml у меня не работает, например, на 2.3.x, но работает как
брелок
Это решение сработало лучше всего. Мне также нужно было захватить android.support.v7.internal.view.menu.ListMenuItemView, чтобы получить стили, применяемые на устройствах с использованием библиотеки совместимости
Chiatar
Это исправление не будет работать с Google Maps v2 - супер-метод должен быть вызван 1-ым, чтобы карты правильно отображались.
Chiatar
5

я нашел это Эврика!

в теме вашего приложения:

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

Ура;)

Фарид Алнамрути
источник
5

для изменения цвета текста пункта меню используйте код ниже

<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>
Мухаммед Абдулла
источник
4

Благодаря 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".

lightkeeper
источник
У меня не работает API 24. Есть идеи? Застрял в этом в течение нескольких дней ... смешно!
Дэвид П
Не уверен, что тебе сказать. Это работает нормально для меня в API 25.
Lightkeeper
3

Вы можете установить цвет программно.

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);
            }

        }
    });
}
Виктор Чой
источник
3

Добавление этого в мой styles.xml работало для меня

<item name="android:textColorPrimary">?android:attr/textColorPrimaryInverse</item>
Асим
источник
2

Просто добавьте это в свою тему

<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

Фам Куан
источник
2
Лучше использовать <style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget">, в противном случае текст кажется слишком маленьким в меню переполнения. Также обратите внимание, что эта техника работает только на Android 5 и выше.
Mr-IDE
2
@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
Bada
источник
1
объясни свой ответ
кодер
1
Что если это не SearchView?
нащий
2

Моя ситуация была настройкой цвета текста в меню настроек (главное меню приложения показывалось при нажатии кнопки меню).

Протестировано в API 16 с библиотекой appcompat-v7-27.0.2 , AppCompatActivityдля MainActivityи AppCompatтемой для приложения в 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влияет ли это на другие элементы, но он контролирует цвет текста меню.


Я искал несколько примеров по этой теме, но все готовые к использованию фрагменты не работали.

Поэтому я хотел исследовать его с помощью исходного кода для библиотеки appcompat-v7 (в частности, с папкой res пакета .aar ).

Хотя в моем случае я использовал Eclipse с разнесенными зависимостями .aar . Так что я мог бы изменить стили по умолчанию и проверить результаты. Не знаю, как взорвать библиотеки для использования с Gradle или Android Studio напрямую. Это заслуживает другого потока исследования.

Поэтому моей целью было найти какой цвет в файле res / values ​​/ values.xml для текста меню (я был почти уверен, что цвет был там).

  1. Я открыл этот файл, затем продублировал все цвета, поместил их под цвета по умолчанию, чтобы переопределить их и назначил #f00 значение.
  2. Запустите приложение.
  3. Многие элементы имели красный фон или цвет текста. И пункты меню тоже. Это было то, что мне было нужно.
  4. Удаляя мои добавленные цвета блоками по 5-10 строк, я заканчивал secondary_text_default_material_lightцветным элементом.
  5. Выполняя поиск по этому имени в файлах в папке res (или лучше в res / colors ), я обнаружил только одно вхождение в файле color / abc_secondary_text_material_light.xml (я использовал Sublime Text для этих операций, чтобы легче было найти нужную вещь).
  6. Вернуться к values.xml 8 использований были найдены для@color/abc_secondary_text_material_light .
  7. Это была легкая тема, так что 4 осталось в 2 темах: Base.ThemeOverlay.AppCompat.LightиPlatform.AppCompat.Light .
  8. Первая тема была дочерней по отношению ко второй, поэтому в этом цветовом ресурсе было только 2 атрибута: android:textColorSecondaryи android:textColorTertiaryв Base.ThemeOverlay.AppCompat.Light.
  9. Изменив их значения непосредственно в файле values.xml и запустив приложение, я обнаружил, что последний правильный атрибут был android:textColorSecondary.
  10. Затем мне понадобилась тема или другой атрибут, чтобы я мог изменить его в style.xml моего приложения (потому что моя тема имела в качестве родителя, Theme.AppCompat.Lightа неThemeOverlay.AppCompat.Light ).
  11. Я искал в том же файле для Base.ThemeOverlay.AppCompat.Light. У него был ребенокThemeOverlay.AppCompat.Light .
  12. В поисках ThemeOverlay.AppCompat.Lightя нашел его использование в Base.Theme.AppCompat.Light.DarkActionBarтеме какactionBarPopupTheme значения атрибута.
  13. Тема моего приложения Theme.AppCompat.Light.DarkActionBarбыла дочерней из найденного, Base.Theme.AppCompat.Light.DarkActionBarпоэтому я мог использовать этот атрибут в моем styles.xml без проблем .
  14. Как видно из приведенного выше примера кода, я создал дочернюю тему из упомянутого ThemeOverlay.AppCompat.Lightи изменил android:textColorSecondaryатрибут.

https://i.imgur.com/LNfKdzC.png

Mortalis
источник
1

Решение Сефи не работает. Можно переопределить внешний вид текста пункта меню параметров, используя метод, описанный выше, но не пункт или меню. Для этого есть по существу 3 способа:

  1. Как изменить цвет фона меню настроек?
  2. Напишите свой собственный вид для отображения и переопределения onCreateOptionsMenu и onPrepareOptionsMenu, чтобы получить желаемые результаты. Обычно я утверждаю, что в этих методах вы можете делать все, что хотите, но вы, вероятно, не захотите вызывать super ().
  3. Скопируйте код из SDK с открытым исходным кодом и настройте его для своего поведения. Реализация меню по умолчанию, используемая Activity, больше не будет применяться.

См. Выпуск 4441: Тема меню пользовательских параметров для получения дополнительной информации.

цепкий
источник
Повторимся ... Решение Sephy работает для пункта меню TextAppearance, хотя я переопределил значение по умолчанию через themes.xml. Кроме того, # 2 или # 3 выше должны знать, что вызов super # onCreateOptionsMenu / super # onPrepareOptionsMenu предназначен для размещения элементов системного меню ... как указано в javadoc для Activity # onCreateOptionsMenu (). Это может / не может иметь значения для вашего приложения.
Стойкий
Sephy описывает, что это должно быть в вашем themes.xml: <item name = "android: itemTextAppearance"> @ style / Text_MenuItemText </ item> Затем определите что-то подобное в вашем styles.xml: <style name = "Text_MenuItemText" > <item name = "android: textSize"> 12dp </ item> <item name = "android: textColor"> # FFFFFF </ item> </ style> Это так просто, как только можно. Вы это имели в виду? Более глубокая настройка меню настроек совсем не легка, но я собираюсь вскоре опубликовать статью об этом в блоге.
Стойкий
1

попробуй этот код ....

 @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);
    }
Anoop
источник
1
на Android> 4.0 я получаюjava.lang.IllegalStateException: A factory has already been set on this LayoutInflater
К кра
1

Если вы хотите установить цвет для отдельного пункта меню, настройка темы панели инструментов не является правильным решением. Для этого вы можете использовать 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_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/menuButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        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>

В приведенном выше фрагменте кода мы используем 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 .

Александр Полещук
источник
0

Вот как вы можете закрасить определенный пункт меню цветом, работает для всех уровней 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);
}
коробка
источник
0

Для изменения цвета текста вы можете просто установить пользовательский вид для MenuItem, а затем вы можете определить цвет для текста.

Пример кода: MenuItem.setActionView ()

досуг
источник
Хотя этот фрагмент кода может решить вопрос, в том числе объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин, по которым вы предлагаете код.
Миша