如何设置选项菜单的字体?

当我创build一个选项菜单的项目似乎默认为本机“无”字体。 当我看着商业应用程序时,他们似乎也做了同样的事情。 是否可以设置选项菜单项的字体大小,颜色重量或字体?

提前致谢。

Solutions Collecting From Web of "如何设置选项菜单的字体?"

您可以自定义选项菜单,包括:

  1. 添加自定义字体

  2. 更改字体大小

  3. 更改字体颜色

  4. 将背景设置为Drawable资源(例如图像,边框,渐变)

要将背景更改为边框或渐变,您必须在res创build一个名为drawable的资源文件夹,并在其中创build边框XML或渐变XML。

这可以通过编程方式完成,如下所示:

 public class CustomMenu extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } public boolean onCreateOptionsMenu(android.view.Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.cool_menu, menu); getLayoutInflater().setFactory(new Factory() { public View onCreateView(String name, Context context, AttributeSet attrs) { if (name.equalsIgnoreCase( "com.android.internal.view.menu.IconMenuItemView")) { try { LayoutInflater li = LayoutInflater.from(context); final View view = li.createView(name, null, attrs); new Handler().post(new Runnable() { public void run() { // set the background drawable if you want that //or keep it default -- either an image, border //gradient, drawable, etc. view.setBackgroundResource(R.drawable.myimage); ((TextView) view).setTextSize(20); // set the text color Typeface face = Typeface.createFromAsset( getAssets(),"OldeEnglish.ttf"); ((TextView) view).setTypeface(face); ((TextView) view).setTextColor(Color.RED); } }); return view; } catch (InflateException e) { //Handle any inflation exception here } catch (ClassNotFoundException e) { //Handle any ClassNotFoundException here } } return null; } }); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.AboutUs: Intent i = new Intent("com.test.demo.ABOUT"); startActivity(i); break; case R.id.preferences: Intent p = new Intent("com.test.demo.PREFS"); startActivity(p); break; case R.id.exit: finish(); break; } return false; } } 

不要忘记在res文件夹中创build名为menu的文件夹,并在menu文件夹内为您的菜单(例如cool_menu.xml )创build一个XML,例如:

 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:title="about"android:id="@+id/AboutUs" /> <item android:title="Prefs" android:id="@+id/preferences" /> <item android:title="Exit" android:id="@+id/exit" /> </menu> 

那么输出将是这样的:

在这里输入图像说明

@Android Stack,当我读到你的答案时,我开始恐慌,认为我将不得不使用一个“工厂”。

我search了一下,我知道你可以使用自定义视图的菜单项。 只需在菜单项上调用setActionView即可 。

 @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); // Inflate the menu items for use in the action bar MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.my_menu, menu); // Get the root inflator. LayoutInflater baseInflater = (LayoutInflater)getBaseContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); // Inflate your custom view. View myCustomView = baseInflater.inflate(R.layout.my_custom_view, null); menu.findItem(R.id.my_custom_menu_icon).setActionView(myCustomView); // If myCustomView has additional children, you might have to inflate them separately here. // In my case, I used buttons in my custom view, and registered onClick listeners at this point. } 

你的my_custom_view实现可以是你想要的任何视图(尽pipe它可能必须有一个LinearLayout作为根元素)。 例如,您可以使用@ R4j在他的答案中提出的TextView + ImageView布局。

在我的使用案例中,我只是把Button对象放到菜单中,然后依靠button的onButtonClick处理程序来响应事件 – 有效地侧移了在包含菜单的活动中处理它们的需要。

(顺便问一下,谢谢!!)

而不是使用菜单的XML资源,使用menu.add代码充气,并使用新的SpannableString()分配自定义字体。

这是一个在Android 4.x上工作的例子:

 @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { ... menu.add(Menu.NONE,1234,1,wrapInSpan(getResources().getString(R.string.item_title))) .setTitleCondensed(getResources().getString(R.string.item_title)); ... } private CharSequence wrapInSpan(CharSequence value) { SpannableStringBuilder sb = new SpannableStringBuilder(value); sb.setSpan(MY_TYPEFACE, 0, value.length(), 0); return sb; } 

需要setTitleCondensed(...)来解决android API中的一个bug:当一个菜单项被选中时,事件被logging下来,并使用titleCondensed来写入日志。 如果titleCondensed未定义,则使用title ,每当要logging的string格式化时, EventLog.writeEvent都会崩溃。

因此,在consendedTitle传递一个非格式的CharSequence来解决这个错误。

testing和工作像魅力:)

 @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu_feedback_filter, menu); for (int i = 0; i < menu.size(); i++) { MenuItem mi = menu.getItem(i); //for aapplying a font to subMenu ... SubMenu subMenu = mi.getSubMenu(); if (subMenu != null && subMenu.size() > 0) { for (int j = 0; j < subMenu.size(); j++) { MenuItem subMenuItem = subMenu.getItem(j); applyFontToMenuItem(subMenuItem, typeface); } } //the method we have create in activity applyFontToMenuItem(mi, typeface); } return super.onCreateOptionsMenu(menu); } private void applyFontToMenuItem(MenuItem mi, Typeface font) { SpannableString mNewTitle = new SpannableString(mi.getTitle()); mNewTitle.setSpan(new CustomTypefaceSpan("", font), 0, mNewTitle.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); mi.setTitle(mNewTitle); } 

自定义跨度类

 import android.graphics.Paint; import android.graphics.Typeface; import android.text.TextPaint; import android.text.style.TypefaceSpan; public class CustomTypefaceSpan extends TypefaceSpan { private final Typeface newType; public CustomTypefaceSpan(String family, Typeface type) { super(family); newType = type; } @Override public void updateDrawState(TextPaint ds) { applyCustomTypeFace(ds, newType); } @Override public void updateMeasureState(TextPaint paint) { applyCustomTypeFace(paint, newType); } private static void applyCustomTypeFace(Paint paint, Typeface tf) { int oldStyle; Typeface old = paint.getTypeface(); if (old == null) { oldStyle = 0; } else { oldStyle = old.getStyle(); } int fake = oldStyle & ~tf.getStyle(); if ((fake & Typeface.BOLD) != 0) { paint.setFakeBoldText(true); } if ((fake & Typeface.ITALIC) != 0) { paint.setTextSkewX(-0.25f); } paint.setTypeface(tf); } } 

我认为Android不支持自定义选项菜单。 但是,你可以尝试另一种方式: http : //www.codeproject.com/Articles/173121/Android-Menus-My-Way
这样,实际上菜单项是一个textview和imageview,所以你可以很容易地改变字体,颜色…

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:layout_gravity="center" android:padding="4dip" android:clickable="true" android:background="@drawable/custom_menu_selector"> <ImageView android:id="@+id/custom_menu_item_icon" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:paddingBottom="2dip" android:paddingTop="2dip"/> <TextView android:id="@+id/custom_menu_item_caption" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#ffffff" android:textSize="12sp" android:gravity="center"/> 

上面的答案都没有为我工作。 我通过以下解决scheme实现了这一点

 public boolean onPrepareOptionsMenu(Menu menu) { MenuItem item = menu.findItem(R.id.menu_name); item.setTitle(someTextToDisplayOnMenu); SpannableString spanString = new SpannableString(item.getTitle().toString()); spanString.setSpan(new TextAppearanceSpan(context,android.R.style.TextAppearance_Medium), 0,spanString.length(), 0); spanString.setSpan(new ForegroundColorSpan(Color.WHITE), 0, spanString.length(), 0); //fix the color to white item.setTitle(spanString); return true; } 

我find的唯一解决scheme是创build一个自定义对话框,当您按菜单button时出现。 布局会是这样的:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Mi cuenta" android:id="@+id/buttonMyAccount" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Ayuda" android:id="@+id/buttonHelp" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Contacto" android:id="@+id/buttonContact" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Acerca de" android:id="@+id/buttonAbout" /> </LinearLayout> 

之后,从Activity类中,在'OnOptionsItemSelected'方法中我写下面的代码:

 @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_settings: Dialog dialog = new Dialog(this); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.options_menu); dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); dialog.show(); Button buttonMyAccount = (Button) dialog.findViewById(R.id.buttonMyAccount); Typeface font = Typeface.createFromAsset(this.getAssets(), "SamsungIF_Rg.ttf"); buttonMyAccount.setTypeface(font); buttonMyAccount.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent itMyAccount = new Intent(getBaseContext(), AccountActivity.class); startActivity(itMyAccount); } }); Button buttonHelp = (Button) dialog.findViewById(R.id.buttonHelp); buttonHelp.setTypeface(font); buttonHelp.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent itAssistant = new Intent(getBaseContext(), AssistantPagerActivity.class); startActivity(itAssistant); } }); Button buttonContact = (Button) dialog.findViewById(R.id.buttonContact); buttonContact.setTypeface(font); buttonContact.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent itContact = new Intent(getBaseContext(), ContactActivity.class); startActivity(itContact); } }); Button buttonAbout = (Button) dialog.findViewById(R.id.buttonAbout); buttonAbout.setTypeface(font); buttonAbout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent itAbout = new Intent(getBaseContext(), AboutActivity.class); startActivity(itAbout); } }); Window window = dialog.getWindow(); WindowManager.LayoutParams wlp = window.getAttributes(); wlp.gravity = Gravity.RIGHT | Gravity.TOP; wlp.y = getSupportActionBar().getHeight(); wlp.width = 300; wlp.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND; window.setAttributes(wlp); return true; default: return super.onOptionsItemSelected(item); } }