Como alterar a cor do texto do item de menu no Android?

175

Posso alterar a cor de fundo de um item de menu no Android?

Informe-me se alguém tiver alguma solução para isso. A última opção será obviamente personalizá-la, mas existe alguma maneira de alterar a cor do texto sem personalizá-la.

tomar sol
fonte
Existe alguém que possa me informar a solução para isso?
26510 sunil
3
Deseja alterar a cor do texto, a cor de fundo da exibição de texto? ou ambos? Ambos são coisas diferentes. Reorganize a pergunta.
Abhinav Saxena

Respostas:

335

Uma linha simples no seu tema :)

<item name="android:actionMenuTextColor">@color/your_color</item>
Muhammad Alfaifi
fonte
19
NOTA: Isso DEVE estar na definição principal do tema do seu aplicativo, NÃO dentro do, actionBarStylepor exemplo. Não funcionará por dentro actionBarStyle, mesmo que isso pareça lógico!
Colin M.
47
Para apoiar as versões mais baixas API usar <item name="actionMenuTextColor">@color/your_color</item>não use o namespace Android
alex.p
5
@ColinM. Tem que entrar em um tema. Se você definir um themeatributo na sua barra de ferramentas, isso funcionará.
precisa saber é o seguinte
2
Não estava funcionando para mim com ou sem android: namespace. Foi adicionado ao tema principal do aplicativo.
CCR
2
Ainda não consigo mudar a cor do texto. Minha cor de texto geral do tema apenas tem preferência. Qualquer ajuda? Nenhuma dessas respostas funciona.
David P
114

Parece que um

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

no meu tema e

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

em styles.xml altere o estilo dos itens da lista, mas não dos itens de menu.

Marcus Wolschon
fonte
5
Isso funciona muito bem para itens de menu de contexto (não itens de menu do botão de menu), que é o que eu estava procurando. Muito mais simples que toda a bagunça do LayoutFactory.
Chubbsondubs 06/06/12
O android:itemTextAppearanceatributo não pode ser colocado em um estilo cujo pai é, parent="@android:style/Widget.Holo.ListPopupWindow"pois isso não será renderizado corretamente. Ele deve estar em um estilo de nível superior, como aquele cujo pai é android:Theme.Holo.Light.DarkActionBar.
toobsco42
Onde devo adicionar <item name = "android: itemTextAppearance"> @ style / myCustomMenuTextApearance </item>?
Bagusflyer
@bagusflyer você deve acrescentar que no estilo raiz do seu tema, ou seja, o estilo que é um filho de Theme.Holoou Theme.Holo.Light.DarkActionBarou similar.
Tash Pemhiwa
86

Você pode alterar a cor do MenuItemtexto facilmente usando em SpannableStringvez de 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
fonte
10
Isso funcionou para mim em ambos os 4,4 e 5+ usando menu.findItem(R.id.menu_item_id);em vez demenu.getItem()
haagmm
1
Também funcionou para mim [usando findItem (...)].
Atordoado
6
soluções funcionam apenas para item no estouro .... i luto para mudar a cor do artigo que é visível através da criação showAsAction: "sempre"
Junaid
56

Se você estiver usando a nova barra de ferramentas, com o tema Theme.AppCompat.Light.NoActionBar, poderá estilizá-la da seguinte maneira.

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

De acordo com os resultados que obtive,
android:textColorPrimaryé a cor do texto que exibe o nome da sua atividade, que é o texto principal da barra de ferramentas.

android:textColorSecondaryé a cor do texto das legendas e o botão de mais opções (3 pontos). (Sim, ele mudou de cor de acordo com esta propriedade!)

android:textColorÉ a cor de todos os outros textos, incluindo o menu.

Finalmente, defina o tema para a barra de ferramentas

<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
fonte
Qual item controla o texto nos botões que são mostrados como ações (texto) na barra de ferramentas? Nem android: textColorPrimary, android: textColorSecondary, nem android: textColor parecem afetá-los.
LarsH
Em resposta à minha pergunta no comentário anterior: android:actionMenuTextColor(consulte stackoverflow.com/a/5538709/423105 ).
LarsH
32

Se você estiver usando o menu <android.support.design.widget.NavigationView />, basta adicionar a linha abaixo NavigationView:

app:itemTextColor="your color"

Também disponível colorTint para ícone, ele substituirá a cor do seu ícone também. Para isso você deve adicionar a linha abaixo:

app:itemIconTint="your color"

Exemplo:

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

Espero que ajude você.

Mihir Trivedi
fonte
Isso alterou os itens aninhados em outro item, mas não o item que contém outros itens. Você sabe como eu poderia mudá-los também?
Dinu Nicolae
@DinuNicolae Você pode postar sua captura de tela de exemplo? Ou forneça mais detalhes.
Mihir Trivedi 23/03
Eu tinha <item> <menu> <dentro dos itens> </menu> </item> e apenas a cor dos itens dentro mudou
Dinu Nicolae
31

Eu fui sobre isso programaticamente assim:

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;
}
Muralikrishna GS
fonte
2
sua resposta me ajudou a definir o texto do MenuItem para negrito. (s.setSpan (new StyleSpan (android.graphics.Typeface.BOLD), 0, s.length (), 0); Obrigado!
Arkadiusz Cieśliński
Esta solução ajudou meu problema. Eu gosto disso, uma vez que não vai depender das condições do tema.
Tomcat
15

Como você pode ver nesta pergunta, você deve:

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

O código acima altera a cor do texto dos itens de ação do menu para API> = v21.

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

Acima está o código da API <v21

Pouya Danesh
fonte
Obrigado. Isso deve ser aceito. É simples e fácil
Pooja
10

Usei a tag html para alterar a cor do texto de um único item quando o item de menu é inflado. Espero que seja útil.

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
fonte
1
Isso não funciona para mim no Marshmallow. O texto é aplicado, mas não a cor.
Ollie C
Em relação ao Marshmallow, provavelmente não funciona pelo mesmo motivo indicado na resposta de max.mustermann: "soluções funcionam apenas para itens em excesso".
30816 Jose_GD #
10

A maneira MAIS SIMPLES de criar cores de menu personalizadas para uma barra de ferramentas única, não para o 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>

barra de ferramentas usual em styles.xml

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

nosso estilo de barra de ferramentas personalizado

<style name="AppTheme.AppBarOverlay.MenuBlue">
    <item name="actionMenuTextColor">@color/blue</item>
</style>
AndrewS
fonte
Funciona bem! Melhor resposta.
bebe
9

no Kotlin, escrevi estas extensões:

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

e usado assim:

menu.findItem(R.id.main_settings).setTitleColor(Color.RED)
Amir Khorsandi
fonte
Realmente gosto desta solução, muito elegante!
21718 Jamil Nawaz
Obrigado, solução simples e rápida. Para API> 24 funciona sem essa segunda função ext
Laszlo
7

A resposta curta é sim. sortudo!
Para fazer isso, você precisa substituir alguns estilos dos estilos padrão do Android:

Primeiro, observe a definição dos temas no 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>

Portanto, a aparência do texto no menu está em @android:style/TextAppearance.Widget.IconMenu.Item
Agora, na definição dos estilos :

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

Portanto, agora temos o nome da cor em questão, se você procurar na pasta de cores dos recursos do sistema:

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

Finalmente, aqui está o que você precisa fazer:

Substitua "TextAppearance.Widget.IconMenu.Item" e crie seu próprio estilo. Em seguida, vincule-o ao seu próprio seletor para torná-lo da maneira que desejar. Espero que isso ajude você. Boa sorte!

Sephy
fonte
Obrigado por responder. Eu fiz o que você sugeriu, mas não mudam a cor do item de menu
Sunil
Na verdade, acabei de ler, lendo mais do menu, que é muito mais complicado do que pensei. Se você não quiser criar seu próprio menu personalizado completo ... Isso vai precisar de mais leitura para mim, vou continuar você postou aqui se eu encontrar mais.
Sephy
Não é possível substituir "TextAppearance.Widget.IconMenu.Item".
peceps
Esta resposta é enganosa. Portanto, a conclusão é que ela não funciona e é muito mais difícil / prolongada do que se pensava originalmente?
speedynomads
6

O menu Opções no Android pode ser personalizado para definir o plano de fundo ou alterar a aparência do texto. A cor do plano de fundo e do texto no menu não pôde ser alterada usando temas e estilos. O código-fonte do Android (data \ res \ layout \ icon_menu_item_layout.xml) usa um item personalizado da classe “com.android.internal.view.menu.IconMenuItem” View para o layout do menu. Podemos fazer alterações na classe acima para personalizar o menu. Para conseguir o mesmo, use a classe de fábrica LayoutInflater e defina a cor do plano de fundo e do texto para a exibição.


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


Abhay Kumar
fonte
3
03-23 19:45:25.134: E/AndroidRuntime(26761): java.lang.IllegalStateException: A factory has already been set on this LayoutInflater
Para Kra
Isso funciona pela primeira vez. Quando você abre o menu pela segunda vez, recebe uma exceção.
LoveForDroid 11/08
6

Obrigado pelo exemplo de código. Eu tive que modificá-lo e fazê-lo funcionar com um menu de contexto. Esta é a minha solução.

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

Para mim, isso funciona com o Android 1.6, 2.03 e 4.03.

Michael Vogl
fonte
Se você está fazendo o que foi dito acima, basta usar a solução Marcus Wolschon. Muito mais simples.
Chubbsondubs 06/06/12
A solução xml não funciona para mim no exemplo 2.3.x, mas isso funciona como um charme - também no 4.x
sunlock
Esta solução funcionou melhor. Eu tive que também capturar android.support.v7.internal.view.menu.ListMenuItemView para obter os estilos aplicados em dispositivos usando a biblioteca de compatibilidade
Chiatar
Essa correção não funcionará com o Google Maps v2 - o super método deve ser chamado 1º para que os mapas sejam renderizados corretamente.
Chiatar
5

eu achei Eureka !!

no seu tema do aplicativo:

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

Aqui está o seu tema da barra de ação:

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

e aqui está o seu tema pop-up:

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

Felicidades ;)

Alnamrouti com tarifa
fonte
5

para alterar a cor do texto do item de menu, use o código abaixo

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

Onde

<style name="menu_item_color">
<item name="android:textColor">@color/app_font_color</item>
</style>
Muhammad Abdullah
fonte
4

Graças a max.musterman, esta é a solução que consegui trabalhar no nível 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);
}

O código codificado Color.BLACKpode se tornar um parâmetro adicional para o setMenuTextColormétodo. Além disso, eu só usei isso para itens de menu que eram android:showAsAction="never".

guarda da luz
fonte
Não está funcionando para mim na API 24. Alguma idéia? Estive preso nisso por dias ... ridículo!
David P
Não tenho certeza do que te dizer. Isso está funcionando bem para mim na API 25.
lightkeeper
3

Você pode definir cores programaticamente.

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

        }
    });
}
Victor Choy
fonte
3

Adicionando isso ao meu styles.xml funcionou para mim

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

Basta adicionar isso ao seu tema

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

Testado na API 21

Pham Quan
fonte
2
É melhor usar <style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget">, caso contrário, o texto parece muito pequeno no menu de estouro. Observe também que essa técnica funciona apenas no Android 5 e superior.
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
Bäda
fonte
1
explique sua resposta
Coder
1
E se não for um SearchView?
nasch 14/09/18
2

Minha situação era configurações de cor do texto no menu de opções (o menu principal do aplicativo era exibido no pressionamento do botão de menu).

Testado na API 16 com a biblioteca appcompat-v7-27.0.2 , AppCompatActivitypara MainActivitye AppCompattema para o aplicativo no 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>

Não sei se isso textColorSecondaryafeta outros elementos, mas controla a cor do texto do menu.


Procurei alguns exemplos sobre o tópico, mas todos os trechos prontos para uso não funcionaram.

Então, eu queria investigar isso com o código-fonte da biblioteca appcompat-v7 (especificamente com a pasta res do pacote .aar ).

Embora, no meu caso, eu usei o Eclipse com dependências .aar explodidas . Para que eu pudesse alterar os estilos padrão e verificar os resultados. Não sei como explodir as bibliotecas para usar diretamente com o Gradle ou o Android Studio . Merece outro segmento de investigação.

Portanto, meu objetivo era descobrir qual cor no arquivo res / values ​​/ values.xml é usada para o texto do menu (eu tinha quase certeza de que a cor estava lá).

  1. Abri o arquivo, depois dupliquei todas as cores, coloque-as abaixo das padrão para substituí-las e atribuí-las #f00 valor a todas elas.
  2. Inicie o aplicativo.
  3. Muitos elementos tinham fundo vermelho ou cor do texto. E os itens de menu também. Era disso que eu precisava.
  4. Removendo minhas cores adicionadas por blocos de 5 a 10 linhas, terminei com o secondary_text_default_material_lightitem de cor.
  5. Pesquisando esse nome nos arquivos da pasta res (ou melhor, em res / colors ), encontrei apenas uma ocorrência no arquivo color / abc_secondary_text_material_light.xml (usei o Sublime Text para essas operações, para que seja mais fácil encontrar o que preciso).
  6. De volta ao values.xml, foram encontrados 8 usos para o @color/abc_secondary_text_material_light.
  7. Como era um tema leve, restavam 4 em 2 temas: Base.ThemeOverlay.AppCompat.Lighte Platform.AppCompat.Light.
  8. O primeiro tema era filho do segundo, então havia apenas 2 atributos com esse recurso de cores: android:textColorSecondarye android:textColorTertiaryno Base.ThemeOverlay.AppCompat.Light.
  9. Alterando seus valores diretamente no values.xml e executando o aplicativo, achei que o atributo correto final era android:textColorSecondary.
  10. Em seguida, eu precisava de um tema ou outro atributo para poder alterá-lo no style.xml do meu aplicativo (porque meu tema tinha como pai o Theme.AppCompat.Lighte não o ThemeOverlay.AppCompat.Light).
  11. Eu procurei no mesmo arquivo pelo Base.ThemeOverlay.AppCompat.Light. Teve um filho ThemeOverlay.AppCompat.Light.
  12. Procurando pelo ThemeOverlay.AppCompat.Light, encontrei seu uso no Base.Theme.AppCompat.Light.DarkActionBartema como o actionBarPopupThemevalor do atributo.
  13. O tema do meu aplicativo Theme.AppCompat.Light.DarkActionBarera filho do encontrado, Base.Theme.AppCompat.Light.DarkActionBarpara que eu pudesse usar esse atributo nos meus styles.xml sem problemas.
  14. Como é visto no código de exemplo acima, criei um tema filho a partir do mencionado ThemeOverlay.AppCompat.Lighte alterei o android:textColorSecondaryatributo.

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

mortalis
fonte
1

A solução de Sephy não funciona. É possível substituir a aparência do texto do item de menu de opções usando o método descrito acima, mas não o item ou menu. Para fazer isso, existem essencialmente três maneiras:

  1. Como alterar a cor de fundo do menu de opções?
  2. Escreva sua própria exibição para exibir e substituir onCreateOptionsMenu e onPrepareOptionsMenu para obter os resultados desejados. Eu afirmo isso geralmente porque você geralmente pode fazer o que quiser nesses métodos, mas provavelmente não vai querer chamar super ().
  3. Copie o código do SDK de código aberto e personalize para o seu comportamento. A implementação do menu padrão usada pelo Activity não será mais aplicada.

Consulte o Problema 4441: Tema do menu Opções personalizadas para obter mais dicas.

Persistente
fonte
Para reiterar ... A solução de Sephy funciona para o item de menu TextAppearance, embora o que fiz foi substituir o padrão por meio de themes.xml. Além disso, os itens 2 ou 3 acima devem estar cientes de que a chamada para super # onCreateOptionsMenu / super # onPrepareOptionsMenu foi projetada para colocar itens de menu do sistema ... conforme indicado no javadoc da Atividade # onCreateOptionsMenu (). Isso pode ou não importar para o seu aplicativo.
Tenacious
O que Sephy está descrevendo é ter isso em seus themes.xml: <item name = "android: itemTextAppearance"> @ style / Text_MenuItemText </item> Em seguida, defina algo assim em seus styles.xml: <style name = "Text_MenuItemText" > <item name = "android: textSize"> 12dp </item> <item name = "android: textColor"> # FFFFFF </item> </style> Isso é o mais fácil possível. Foi isso que você quis dizer? A personalização mais profunda do menu de opções não é nada fácil, mas pretendo postar um artigo no blog em breve.
Tenacious
1

tente este código ....

 @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
fonte
1
no Android> 4.0 eu estou recebendojava.lang.IllegalStateException: A factory has already been set on this LayoutInflater
To Kra 23/03
1

Se você deseja definir cores para um item de menu individual, a personalização de um tema da barra de ferramentas não é a solução certa. Para conseguir isso, você pode usar o android: actionLayout e uma exibição de ação para o item de menu.

Primeiro, crie um arquivo de layout XML para a visualização de ação. Neste exemplo, usamos um botão como uma visualização de ação:

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>

No snippet de código acima, usamos android:textColor="?android:attr/colorAccent"para personalizar a cor do texto do botão.

Em seguida, no seu arquivo de layout XML para o menu, inclua app:actionLayout="@layout/menu_button"como mostrado abaixo:

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>

Última substituição do onCreateOptionsMenu()método em sua atividade:

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

... ou fragmento:

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

Para mais detalhes sobre visualizações de ação, consulte o guia do desenvolvedor do Android .

Alexander Poleschuk
fonte
0

É assim que você pode colorir um item de menu específico com cores e funciona em todos os níveis da 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));
                                }
                            }
                        }
                    }
                });
            }
        }
    }
}

Ao fazer isso, você perde o efeito seletor de plano de fundo, eis o código para aplicar um seletor de plano de fundo personalizado a todos os filhos do item de menu.

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

Aqui está a função auxiliar também:

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);
}
caixa
fonte
0

Para alterar a cor do texto, você pode apenas definir uma exibição personalizada para o MenuItem e, em seguida, definir a cor do texto.

Código de exemplo: MenuItem.setActionView ()

lazer
fonte
Embora esse trecho de código possa resolver a questão, incluir uma explicação realmente ajuda a melhorar a qualidade da sua postagem. Lembre-se de que você está respondendo à pergunta dos leitores no futuro e essas pessoas podem não saber os motivos da sua sugestão de código.
precisa