如何更改Android菜单项的自定义字体?

如何更改Android菜单项的自定义字体?,android,menuitem,Android,Menuitem,我有以下Android Java和XML代码。我想更改应用程序菜单项的字体。我只知道我们可以使用setTypeface更改TextView的字体,但无法找到菜单项的任何字体 JAVA代码-: @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main, menu);

我有以下Android Java和XML代码。我想更改应用程序菜单项的字体。我只知道我们可以使用setTypeface更改TextView的字体,但无法找到菜单项的任何字体

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;
   }
}
        // 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);
<?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/settings"
        android:onClick="openSettings"
        android:title="@string/settings"
        app:showAsAction="never" />
    <item
        android:id="@+id/about"
        android:onClick="openAbout"
        android:title="@string/about"
        app:showAsAction="never" />
</menu>
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中设置以下内容之一

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

案例2如果您未使用支持库:

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

背景可绘制(背景透明状态)有助于在自定义布局上获得触摸反馈:

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

...

在添加带有
字体span
的菜单项时,也可以使用
SpannableStringBuilder
。对于每个菜单项,执行以下操作

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);
TypefaceSpan=新的字体span(“”);
SpannableStringBuilder title=新的SpannableStringBuilder(“我的菜单项标题”);
title.setSpan(跨度,0,title.length(),0);
menu.add(menu.NONE、id、index、title);
XML


在活动中或在片段中

@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);
    }
@覆盖
创建选项菜单(菜单菜单,菜单充气机){
Typeface=Typeface.createFromAsset(getActivity().getAssets(),“fonts/OpenSans Regular.ttf”);//此
TypefaceSpan face=新的TypefaceSpan(“”;//或此
SpannableStringBuilder title=新的SpannableStringBuilder(getContext().getString(R.string.edit));
title.setSpan(面,0,title.length(),0);
menu.add(menu.NONE,R.id.action_edit,0,title);//这个
MenuItem MenuItem=menu.findItem(R.id.action_edit);//或
menuItem.setTitle(标题);
super.onCreateOptions菜单(菜单,充气机);
}

我发现这个解决方案对我很有用。希望它能帮助全新的冲浪者

您的菜单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>

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

在您的活动或片段中:

@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;
   }
}
        // 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);
<?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/settings"
        android:onClick="openSettings"
        android:title="@string/settings"
        app:showAsAction="never" />
    <item
        android:id="@+id/about"
        android:onClick="openAbout"
        android:title="@string/about"
        app:showAsAction="never" />
</menu>
//根据上面的布局为菜单充气
充气机。充气(菜单、菜单);
//设置字体类型面
if(setCustomFontType){
final MenuItem MenuItem=menu.findItem(R.id.update);
字符串title=menuItem.getTitle().toString();
按钮菜单=(按钮)菜单项。getActionView();
按钮菜单。设置字体(“”);
按钮菜单设置文本(标题);
按钮菜单。设置颜色(颜色。白色);
按钮菜单.setBackgroundColor(_getResources().getColor(R.color.transparent_color));
按钮菜单.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图){
onOptionsItemSelected(菜单项);
}
});
}
super.onCreateOptions菜单(菜单,充气机);

只需将导航视图的itemTextAppearance属性设置为系统或自定义样式:

 <android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_main_navigation"
    app:itemBackground="@color/white"
    app:itemTextAppearance="@style/TextAppearance.AppCompat"
    app:itemTextColor="@color/saintpatrickblue"
    app:menu="@menu/activity_main_navigation_drawer"/>

在styles.xml中创建样式

 <style name="Style_TextView">
            <item name="fontFamily">@font/myriadproregular</item>
 </style>

注意:它适用于android.support.design.widget.NavigationView

如果您的应用程序只需要在android ie(API级别28)及以上版本上运行,您可以从中的构建。否则,您可以使用如下所示的CustomTypeface span类:

public boolean onPrepareOptionsMenu(Menu menu) {
    int customFontId = R.font.metropolis_medium;
    for (int i = 0; i < menu.size(); i++) {
        MenuItem menuItem = menu.getItem(i);
        String menuTitle = menuItem.getTitle().toString();
        Typeface typeface = ResourcesCompat.getFont(this, customFontId);
        SpannableString spannableString = new SpannableString(menuTitle);
        // For demonstration purposes only, if you need to support < API 28 just use the CustomTypefaceSpan class only.
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
            TypefaceSpan typefaceSpan = typeface != null ?
                    new TypefaceSpan(typeface) :
                    new TypefaceSpan("sans-serif");
            spannableString.setSpan(typefaceSpan, 0, menuTitle.length(), 
                    Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        } else {
            CustomTypefaceSpan customTypefaceSpan = typeface != null ?
                    new CustomTypefaceSpan(typeface) :
                    new CustomTypefaceSpan(Typeface.defaultFromStyle(Typeface.NORMAL));
            spannableString.setSpan(customTypefaceSpan, 0, menuTitle.length(),
                    Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        }
        menuItem.setTitle(spannableString);
    }
    return true;
}
public boolean onprepareOptions菜单(菜单){
int customFontId=R.font.metropolis\u medium;
对于(int i=0;i=android.os.Build.VERSION\u code.P){
TypefaceSpan TypefaceSpan=typeface!=null?
新字体跨度(字体):
新的字体跨度(“无衬线”);
spannableString.setSpan(字体span,0,menutile.length(),
跨度。跨度(不包括在内);
}否则{
CustomTypeface span CustomTypeface span=字体!=空?
新自定义字体跨度(字体):
新的CustomTypefaceSpan(Typeface.defaultFromStyle(Typeface.NORMAL));
spannableString.setSpan(自定义字体span,0,menutile.length(),
跨度。跨度(不包括在内);
}
menuItem.setTitle(spannableString);
}
返回true;
}
main.menu.xml:

@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;
   }
}
        // 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);
<?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/settings"
        android:onClick="openSettings"
        android:title="@string/settings"
        app:showAsAction="never" />
    <item
        android:id="@+id/about"
        android:onClick="openAbout"
        android:title="@string/about"
        app:showAsAction="never" />
</menu>

之前和之后:

@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;
   }
}
        // 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);
<?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/settings"
        android:onClick="openSettings"
        android:title="@string/settings"
        app:showAsAction="never" />
    <item
        android:id="@+id/about"
        android:onClick="openAbout"
        android:title="@string/about"
        app:showAsAction="never" />
</menu>

只需将您选择的字体添加到基本应用程序主题中即可。请注意,这将使选定字体成为任何未指定字体属性的基础字体