如何更改 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
How to change Custom Font of Android Menu Item?
提问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 SpannableStringBuilder
when 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:
之前和之后:
回答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>