Как изменить пользовательский шрифт элемента меню 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 для пункта меню.

Ответ 1

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

Во-первых, в вашем меню 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>

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

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


ИЗМЕНИТЬ:
Если вы используете библиотеку поддержки и свою активность. Тема расширяет AppCompatTheme, вы можете получить типичный эффект " пульсации" для более удобной сенсорной обратной связи. Просто замените пользовательский фон:

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

Ответ 2

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

Ответ 3

Вы также можете использовать 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);

Ответ 4

Я нашел, что это решение полезно для меня. Надеюсь, это поможет совершенно новым серферам.

ваше меню main.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/item1"
  android:title="User"
  android:orderInCategory="100"
  android:visible="true"
  app:showAsAction="always"
  app:actionViewClass="android.widget.Button"
/>
</menu>

После того, как вы наполнили пользовательское меню, вы можете сделать ссылку на элемент меню. Когда вы получите ссылку на пункт меню, вы сможете настроить элемент для отображения значка и текста Юникода. Файл образа значка должен быть сохранен в

папка

res/drawable.

@Override
   public boolean onCreateOptionsMenu(Menu menu) {
     // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);

   //reference to the item of the menu
   MenuItem i=menu.findItem(R.id.item1);
   Button button_menu =(Button) i.getActionView();

   if(itemuser!=null){
   // Create Typeface object to use unicode font in assets folder
   Typeface font= Typeface.createFromAsset(getApplicationContext().getAssets(),"fonts/arial.ttf");
   // Set unicode font to menu item
   button_menu .setTypeface(font);  
   // Set item text and color
   button_menu .setText(getResources().getString(R.string._text));
   button_menu .setTextColor(Color.WHITE);
   // Make item background transparent
   button_menu .setBackgroundColor(Color.TRANSPARENT);
   // Show icon next to the text
   Drawable icon=getApplicationContext().getResources().getDrawable( R.drawable.user);
   button_menu .setCompoundDrawablesWithIntrinsicBounds( icon, null, null, null );
}

return true;

   }

Ответ 5

Ответ от @brahmyadigopula работает хорошо.

Вот только более полная версия для упрощения:

Меню

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <item
        android:id="@+id/update"
        android:showAsAction="always"
        android:title="@string/menu_update"
        tools:ignore="UnusedAttribute"
        android:actionViewClass="android.widget.Button"/>
</menu>

В вашей деятельности или фрагменте:

        // Inflater the menu based on the layout above
        inflater.inflate(menuRes, menu);


        // Set font type face
        if (setCustomFontType){
            final MenuItem menuItem = menu.findItem(R.id.update);
            String title = menuItem.getTitle().toString();

            Button button_menu = (Button) menuItem.getActionView();
            button_menu.setTypeface("<REPLACE_WITH_FONT_NAME>");
            button_menu.setText(title);
            button_menu.setTextColor(Color.WHITE);
            button_menu.setBackgroundColor(_getResources().getColor(R.color.transparent_color));
            button_menu.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    onOptionsItemSelected(menuItem);
                }
            });
        }

        super.onCreateOptionsMenu(menu, inflater);