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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21942533/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:20:26  来源:igfitidea点击:

How to change Custom Font of Android Menu Item?

androidmenuitem

提问by Anshuman Pattnaik

I have the following Android Java and XML code. I want to change the font of Menu Items of my app. I know only that we can change the font of TextView using setTypeface but not able to find anyway for Menu Item.

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

JAVA Code-:

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

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>

I want to change the font of two menu item , but don't know how to integrate settypface for Menu Item.

我想更改两个菜单项的字体,但不知道如何为菜单项集成 settypface。

回答by araks

you have to provide a custom layout for the menu item.

您必须为菜单项提供自定义布局。

First, in your menu XML set one of the following

首先,在您的菜单 XML 中设置以下之一

CASE 1if you are using the support library:

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 2if you are notusing the support library:

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>

Then in the actionLayout (layout_menu_save.xml in my example) write the following:

然后在 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>

The background drawable (background_transparent_stateful) is useful for having touch feedback on your custom layout:

背景可绘制对象 (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>

This way you will have a text with custom font on the left as a label with an icon on the right.

这样,您将在左侧有一个带有自定义字体的文本作为带有右侧图标的标签。

Obviously you can customize the layout as you prefer!

显然,您可以根据自己的喜好自定义布局!


EDIT:
If you are using the support library and your activity Theme extends the AppCompatTheme you can get the typical Lollipop "ripple effect" for a better looking touch feedback. Just replace the custom background with:


编辑
如果您使用支持库并且您的活动主题扩展了 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>

回答by Suman

Create Style in styles.xml

在styles.xml 中创建样式

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

Add Below code into android.support.design.widget.NavigationView

将下面的代码添加到 android.support.design.widget.NavigationView

 app:itemTextAppearance="@style/Style_TextView"

Note: It works for android.support.design.widget.NavigationView

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

回答by Simo Nyathi

Just add the font of your choice to your base application theme. Note that that makes the selected font the base font for any unspecified font attributes.

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

    <item name="android:fontFamily">@font/your_font</item>

回答by NickUnuchek

XML

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>

IN ACTIVITY OR IN FRAGMENT

在活动中或在片段中

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

回答by Stephen Johnson

You can also use a SpannableStringBuilderwhen you add a menu item with a TypefaceSpan. For each menu item do something like

您也可以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);

回答by shash678

If your app only needs to work on Android Pie (API level 28) and above you can construct a TypefaceSpanfrom a Typefacein onPrepareOptionsMenu. Otherwise you can use a CustomTypefaceSpanclass like this answersuggests:

如果您的应用程序只需要在Android上工作P即(API等级28)和上面可以构建一个TypefaceSpan字样onPrepareOptionsMenu。否则,您可以使用像这个答案建议的CustomTypefaceSpan类:

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

main.menu.xml:

主菜单.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/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>

Before & After:

之前和之后:

Before & After

之前和之后

回答by brahmy adigopula

I found this solution is usefull for me .hope it will help full new surfers.

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

your menu main.xml

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

After you inflated the custom menu, you can make a reference to the item of the menu. When you obtain the reference to the menu item, you will be able to customize the item to show icon and Unicode text. Your icon image file has to be stored in the

自定义菜单膨胀后,您可以引用菜单项。当您获得对菜单项的引用时,您将能够自定义该项目以显示图标和 Unicode 文本。您的图标图像文件必须存储在

res/drawable folder.

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;

   }

回答by Joolah

The answer by @brahmyadigopula works well.

@brahmyadigopula 的答案效果很好。

Here is just a more complete version for the sake of simplification:

为了简化起见,这里只是一个更完整的版本:

The Menu

菜单

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

In your Activity or Fragment:

在您的活动或片段中:

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

回答by christian mini

Simply set itemTextAppearanceproperty of the NavigationViewto system or custom style:

只需设置itemTextAppearance的财产NavigationView系统或自定义样式:

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

回答by Android Geek

If you are using android.support.design library then

如果您使用的是 android.support.design 库,那么

app:itemTextAppearance="@style/bottom_navigation_textappreance"

app:itemTextAppearance="@style/bottom_navigation_textappreance"

above will work but if you are using Material design the below properties will work

上面会起作用,但如果您使用材料设计,下面的属性将起作用

app:itemTextAppearanceActive="@style/bottom_navigation_textappreance" app:itemTextAppearanceInactive="@style/bottom_navigation_textappreance"

app:itemTextAppearanceActive="@style/bottom_navigation_textappreance" app:itemTextAppearanceInactive="@style/bottom_navigation_textappreance"

<style name="bottom_navigation_textappreance" parent="Widget.Design.BottomNavigationView"> <item name="fontFamily">@font/fira_sans_bold</item> </style>

<style name="bottom_navigation_textappreance" parent="Widget.Design.BottomNavigationView"> <item name="fontFamily">@font/fira_sans_bold</item> </style>