Как изменить пользовательский шрифт элемента меню Android?

У меня есть следующий код Java и XML для Android. Я хочу изменить шрифт пунктов меню моего приложения. Я знаю только, что мы можем изменить шрифт TextView с помощью setTypeface, но не можем найти в любом случае пункт меню.

Код JAVA:

@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_refresh1: Toast.makeText(this, "Item1 Selected", Toast.LENGTH_SHORT) .show(); break; case R.id.action_refresh2: Toast.makeText(this, "Item2 Selected", Toast.LENGTH_SHORT) .show(); break; default: break; } } 

XML-код:

 <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/action_refresh1" android:orderInCategory="100" android:showAsAction="always" android:title="Item1"/> <item android:id="@+id/action_refresh2" android:orderInCategory="100" android:showAsAction="always" android:title="Item2"/> </menu> 

Я хочу изменить шрифт двух пунктов меню, но не знаю, как интегрировать settypface для пункта меню.

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

Во-первых, в вашем меню XML установлен один из следующих

CASE 1, если вы используете библиотеку поддержки:

 <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_save" android:title="@string/action_save" android:icon="@drawable/ic_action_save" android:orderInCategory="100" app:showAsAction="always" app:actionLayout="@layout/layout_menu_save"/> </menu> 

CASE 2, если вы не используете библиотеку поддержки:

 <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/action_save" android:title="@string/action_save" android:icon="@drawable/ic_action_save" android:orderInCategory="100" android:showAsAction="always" android:actionLayout="@layout/layout_menu_save"/> </menu> 

Затем в actionLayout (layout_menu_save.xml в моем примере) напишите следующее:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="match_parent" android:background="@drawable/background_transparent_stateful"> <com.example.YourCustomTypefaceTextView android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:gravity="center_vertical" android:text="@string/action_save"/> <ImageView android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:gravity="center_vertical" android:src="@drawable/ic_action_save" android:contentDescription="@string/action_save"/> </LinearLayout> 

Фоновый чертеж (background_transparent_stateful) полезен для получения обратной связи касательно вашего пользовательского макета:

 <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_pressed="true" android:drawable="#20FFFFFF"> </item> <item android:drawable="@android:color/transparent"> </item> </selector> 

Таким образом, у вас будет текст с настраиваемым шрифтом слева в виде метки с иконкой справа.

Очевидно, вы можете настроить макет по своему усмотрению!

EDIT :
Если вы используете библиотеку поддержки и свою активность. Тема расширяет AppCompatTheme, вы можете получить типичный эффект « пульсации » Lollipop для лучшей сенсорной обратной связи. Просто замените пользовательский фон:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="match_parent" android:background="?attr/selectableItemBackgroundBorderless"> ... </LinearLayout> 

Вы также можете использовать SpannableStringBuilder когда вы добавляете элемент меню с помощью TypefaceSpan . Для каждого пункта меню сделайте что-то вроде

 TypefaceSpan span = new TypefaceSpan("<REPLACE_WITH_FONT_NAME>"); SpannableStringBuilder title = new SpannableStringBuilder("My Menu Item Title"); title.setSpan(span, 0, title.length(), 0); menu.add(Menu.NONE, id, index, title); 

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/action_edit" android:title="@string/edit" android:visible="true" app:showAsAction="always" /> </menu> 

В ДЕЯТЕЛЬНОСТИ ИЛИ В ФРАГМЕНТЕ

 @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { Typeface face = Typeface.createFromAsset(getActivity().getAssets(),"fonts/OpenSans-Regular.ttf"); // THIS TypefaceSpan face = new TypefaceSpan("<REPLACE_WITH_FONT_NAME>"); // OR THIS SpannableStringBuilder title = new SpannableStringBuilder(getContext().getString(R.string.edit)); title.setSpan(face, 0, title.length(), 0); menu.add(Menu.NONE, R.id.action_edit, 0, title); // THIS MenuItem menuItem = menu.findItem(R.id.action_edit); // OR THIS menuItem.setTitle(title); super.onCreateOptionsMenu(menu, inflater); }