Czy mogę zmienić kolor tła elementu menu w systemie Android?
Daj mi znać, jeśli ktoś ma jakieś rozwiązanie tego problemu. Ostatnią opcją będzie oczywiście dostosowanie go, ale czy istnieje sposób na zmianę koloru tekstu bez dostosowywania go.
Czy mogę zmienić kolor tła elementu menu w systemie Android?
Daj mi znać, jeśli ktoś ma jakieś rozwiązanie tego problemu. Ostatnią opcją będzie oczywiście dostosowanie go, ale czy istnieje sposób na zmianę koloru tekstu bez dostosowywania go.
Odpowiedzi:
Jedna prosta linia w Twoim motywie :)
<item name="android:actionMenuTextColor">@color/your_color</item>
actionBarStyle
na przykład. To nie zadziała wewnątrz actionBarStyle
, nawet jeśli wydaje się to logiczne!
<item name="actionMenuTextColor">@color/your_color</item>
, nie używaj przestrzeni nazw Androida
theme
atrybut na pasku narzędzi, zadziała.
Wygląda na to, że plik
<item name="android:itemTextAppearance">@style/myCustomMenuTextAppearance</item>
w moim motywie i
<style name="myCustomMenuTextAppearance" parent="@android:style/TextAppearance.Widget.IconMenu.Item">
<item name="android:textColor">@android:color/primary_text_dark</item>
</style>
w styles.xml zmieniają styl elementów listy, ale nie elementów menu.
android:itemTextAppearance
Atrybut nie może być umieszczony w stylu, którego rodzic jest parent="@android:style/Widget.Holo.ListPopupWindow"
od tego nie uczyni prawidłowo. Musi być w stylu najwyższego poziomu, takim jak ten, którego rodzicem jest android:Theme.Holo.Light.DarkActionBar
.
Theme.Holo
lub Theme.Holo.Light.DarkActionBar
lub podobny.
Możesz łatwo zmienić kolor MenuItem
tekstu, używając SpannableString
zamiast 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);
}
menu.findItem(R.id.menu_item_id);
zamiastmenu.getItem()
Jeśli używasz nowego paska narzędzi z motywem Theme.AppCompat.Light.NoActionBar
, możesz stylizować go w następujący sposób.
<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>`
Zgodnie z wynikami, które otrzymałem,
android:textColorPrimary
to kolor tekstu wyświetlający nazwę Twojej aktywności, który jest podstawowym tekstem paska narzędzi.
android:textColorSecondary
to kolor tekstu napisów i przycisku więcej opcji (3 kropki). (Tak, zmienił kolor zgodnie z tą właściwością!)
android:textColor
Jest kolorem wszystkich innych tekstów, w tym menu.
Na koniec ustaw motyw na pasku narzędzi
<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"/>
android:actionMenuTextColor
(patrz stackoverflow.com/a/5538709/423105 ).
Jeśli używasz menu jako, <android.support.design.widget.NavigationView />
po prostu dodaj poniższy wiersz NavigationView
:
app:itemTextColor="your color"
Dostępny również odcień koloru dla ikony, zastąpi on również kolor ikony. W tym celu musisz dodać poniższy wiersz:
app:itemIconTint="your color"
Przykład:
<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"/>
Mam nadzieję, że to ci pomoże.
Robiłem to programowo w ten sposób:
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;
}
jak widzisz w tym pytaniu powinieneś:
<item name="android:textColorPrimary">yourColor</item>
Powyższy kod zmienia kolor tekstu pozycji czynności menu dla API> = v21.
<item name="actionMenuTextColor">@android:color/holo_green_light</item>
Powyżej znajduje się kod API <v21
Użyłem tagu HTML, aby zmienić kolor tekstu pojedynczego elementu, gdy element menu jest zawyżony. Mam nadzieję, że to byłoby pomocne.
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;
}
NAJPROSTSZY sposób tworzenia niestandardowego koloru menu dla pojedynczego paska narzędzi, a nie dla 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>
zwykły pasek narzędzi w styles.xml
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>
nasz niestandardowy styl paska narzędzi
<style name="AppTheme.AppBarOverlay.MenuBlue">
<item name="actionMenuTextColor">@color/blue</item>
</style>
w Kotlinie napisałem te rozszerzenia:
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)
}
}
i używane w ten sposób:
menu.findItem(R.id.main_settings).setTitleColor(Color.RED)
Krótka odpowiedź brzmi: TAK. Szczęściarz!
Aby to zrobić, musisz zastąpić niektóre style domyślnych stylów Androida:
Najpierw spójrz na definicję motywów w systemie 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>
Tak więc wygląd tekstu w menu znajduje się w @android:style/TextAppearance.Widget.IconMenu.Item
Teraz, w definicji stylów :
<style name="TextAppearance.Widget.IconMenu.Item" parent="TextAppearance.Small">
<item name="android:textColor">?textColorPrimaryInverse</item>
</style>
Więc teraz mamy nazwę danego koloru, jeśli spojrzysz na folder kolorów zasobów systemu:
<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>
Wreszcie, oto, co musisz zrobić:
Zastąp „TextAppearance.Widget.IconMenu.Item” i utwórz własny styl. Następnie połącz go z własnym selektorem, aby dostosować go do swoich potrzeb. Mam nadzieję, że to ci pomoże. Powodzenia!
Menu opcji w systemie Android można dostosować, aby ustawić tło lub zmienić wygląd tekstu. Nie można zmienić koloru tła i tekstu w menu za pomocą motywów i stylów. Kod źródłowy Androida (data \ res \ layout \ icon_menu_item_layout.xml) używa niestandardowego elementu klasy „com.android.internal.view.menu.IconMenuItem” widoku dla układu menu. Możemy dokonać zmian w powyższej klasie, aby dostosować menu. Aby osiągnąć to samo, użyj klasy fabrycznej LayoutInflater i ustaw kolor tła i tekstu dla widoku.
@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
Dzięki za przykładowy kod. Musiałem go zmodyfikować, aby działał z menu kontekstowym. To jest moje rozwiązanie.
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);
}
U mnie to działa z Androidem 1.6, 2.03 i 4.03.
znalazłem to Eureka !!
w motywie aplikacji:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:actionBarStyle">@style/ActionBarTheme</item>
<!-- backward compatibility -->
<item name="actionBarStyle">@style/ActionBarTheme</item>
</style>
oto motyw paska akcji:
<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>
a oto motyw wyskakującego okienka:
<style name="ActionBarPopupTheme">
<item name="android:textColor">@color/menu_text_color</item>
<item name="android:background">@color/menu_bg_color</item>
</style>
Twoje zdrowie ;)
aby zmienić kolor tekstu pozycji menu użyj poniższego kodu
<style name="AppToolbar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:itemTextAppearance">@style/menu_item_color</item>
</style>
gdzie
<style name="menu_item_color">
<item name="android:textColor">@color/app_font_color</item>
</style>
Dzięki max.musterman, oto rozwiązanie, które uzyskałem na poziomie 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);
}
Zakodowany na stałe Color.BLACK
mógłby stać się dodatkowym parametrem setMenuTextColor
metody. Użyłem tego tylko do pozycji menu, które były android:showAsAction="never"
.
Możesz ustawić kolor programowo.
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);
}
}
});
}
Po prostu dodaj to do swojego motywu
<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>
Testowane na API 21
<style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget">
, w przeciwnym razie tekst będzie wyglądał za mały w rozszerzonym menu. Pamiętaj również, że ta technika działa tylko w systemie Android 5 i nowszych.
@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
Moja sytuacja to ustawienia koloru tekstu w menu opcji (główne menu aplikacji pokazane po naciśnięciu przycisku menu).
Testowane w API 16 z biblioteką appcompat-v7-27.0.2 , AppCompatActivity
dla MainActivity
i AppCompat
motywem dla aplikacji w 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>
Nie wiem, czy textColorSecondary
ma to wpływ na inne elementy, ale steruje kolorem tekstu menu.
Przeszukałem kilka przykładów na ten temat, ale wszystkie gotowe do użycia fragmenty nie działały.
Dlatego chciałem to zbadać z kodem źródłowym biblioteki appcompat-v7 (szczególnie z folderem res pakietu .aar ).
Chociaż w moim przypadku użyłem Eclipse z eksplodowanymi zależnościami .aar . Mogłem więc zmienić domyślne style i sprawdzić wyniki. Nie wiem, jak rozbić biblioteki, które mają być używane bezpośrednio z Gradle lub Android Studio . Zasługuje na kolejny wątek śledztwa.
Więc moim celem było znalezienie koloru w pliku res / values / values.xml używanego w tekście menu (byłem prawie pewien, że kolor tam jest).
#f00
wartość do wszystkich.secondary_text_default_material_light
elementem kolorowym.@color/abc_secondary_text_material_light
.Base.ThemeOverlay.AppCompat.Light
iPlatform.AppCompat.Light
.android:textColorSecondary
oraz android:textColorTertiary
w Base.ThemeOverlay.AppCompat.Light
.android:textColorSecondary
.Theme.AppCompat.Light
a nie ThemeOverlay.AppCompat.Light
).Base.ThemeOverlay.AppCompat.Light
. Miał dzieckoThemeOverlay.AppCompat.Light
.ThemeOverlay.AppCompat.Light
, znalazłem jego użycie w Base.Theme.AppCompat.Light.DarkActionBar
motywie jakoactionBarPopupTheme
wartość atrybutu.Theme.AppCompat.Light.DarkActionBar
był potomkiem znalezionego, Base.Theme.AppCompat.Light.DarkActionBar
więc mogłem użyć tego atrybutu w pliku styles.xml bez problemu .ThemeOverlay.AppCompat.Light
i zmieniłem android:textColorSecondary
atrybut.Rozwiązanie Sephy nie działa. Możliwe jest nadpisanie wyglądu tekstu pozycji menu opcji za pomocą metody opisanej powyżej, ale nie elementu lub menu. Aby to zrobić, istnieją zasadniczo 3 sposoby:
Więcej wskazówek można znaleźć w numerze 4441: Motyw menu opcji niestandardowych .
wypróbuj ten kod ....
@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);
}
java.lang.IllegalStateException: A factory has already been set on this LayoutInflater
Jeśli chcesz ustawić kolor dla pojedynczego elementu menu, dostosowywanie motywu paska narzędzi nie jest właściwym rozwiązaniem. Aby to osiągnąć, możesz skorzystać z android: actionLayout i widoku akcji dla elementu menu.
Najpierw utwórz plik układu XML dla widoku akcji. W tym przykładzie używamy przycisku jako widoku akcji:
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>
W powyższym fragmencie kodu używamy android:textColor="?android:attr/colorAccent"
do dostosowania koloru tekstu przycisku.
Następnie w pliku układu XML dla menu umieść, app:actionLayout="@layout/menu_button"
jak pokazano poniżej:
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>
Ostatnia zmiana onCreateOptionsMenu()
metody w swoim działaniu:
@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;
}
... lub fragment:
@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
});
}
Więcej informacji na temat widoków akcji można znaleźć w podręczniku programisty Androida .
Oto jak można pokolorować konkretną pozycję menu kolorem, działa na wszystkich poziomach 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));
}
}
}
}
});
}
}
}
}
W ten sposób tracisz efekt selektora tła, więc oto kod do zastosowania niestandardowego selektora tła do wszystkich elementów podrzędnych pozycji 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);
}
}
}
}
}
});
}
}
}
}
Oto również funkcja pomocnicza:
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);
}
Aby zmienić kolor tekstu, możesz po prostu ustawić widok niestandardowy dla MenuItem, a następnie zdefiniować kolor tekstu.
Przykładowy kod: MenuItem.setActionView ()