Как изменить цвет текста элемента меню в Android? - PullRequest
144 голосов
/ 19 августа 2010

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

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

Ответы [ 25 ]

6 голосов
/ 13 января 2017

ПРОСТОЙ способ сделать пользовательский цвет меню для отдельной панели инструментов, а не для 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>
5 голосов
/ 02 июня 2011

Меню параметров в 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);
}


5 голосов
/ 07 июля 2015

я нашел его, Эврика !!

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

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

Приветствия;)

4 голосов
/ 01 ноября 2016

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

3 голосов
/ 03 августа 2018

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

<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>
2 голосов
/ 03 апреля 2018

в Котлине я написал эти расширения:

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)
2 голосов
/ 15 января 2018

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

Протестировано в 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 file (я использовал Sublime Text для этих операций, чтобы легче было найти нужную вещь).
  6. Назад к values.xml 8 было найдено использование для @color/abc_secondary_text_material_light.
  7. Это была тема Light , поэтому 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

2 голосов
/ 13 мая 2017

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

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

        }
    });
}
2 голосов
/ 09 марта 2017
@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
2 голосов
/ 09 сентября 2016

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

<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

...