How to set the font for the Options menu?

When I create the options menu, the default elements have their own sans font by default. When I watch commercial applications, they seem to do the same. Can I set the font size, color, or font for Option menu items?

Thanks in advance.

+32
android
Nov 09 '10 at 15:57
source share
7 answers

You can customize the options menu, including:

  • Add custom font

  • Change font size

  • Change font color

  • Set the background for a paintable resource (e.g. image, border, gradient)

To change the background to a border or gradient, you need to create a resource folder in res called drawable , and inside it create an XML or gradient XML border.

All this can be done programmatically, as shown below:

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

Do not forget to create a folder with the name menu in the res folder, and inside the menu folder, create XML for your menu (for example, cool_menu.xml ), for example:

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

Then the output will be something like this:

enter image description here

+64
Jul 07 '12 at 16:10
source share

@Android Stack, when I read your answer, I started to panic, thinking that I would have to use the "factory".

I searched a bit and I found out that you can use custom views for menu items. Just call setActionView in the menu item.

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

Your implementation of my_custom_view can be any view you want (although perhaps LinearLayout should be the root element). For example, you can use the TextView + ImageView layout that @ R4j offers in your answer.

In my use case, I simply put Button objects in it, and then relied on the onButtonClick handler onButtonClick buttons to respond to events - effectively overstepping the need to handle them in an activity that contains a menu.

(Great question, by the way. Thanks !!)

+8
Jun 29 '14 at 1:03
source share

Instead of using an XML resource for a menu, inflate it from the code using menu.add and use the new SpannableString () to assign a custom font.

Here is an example of working with 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(...) required to bypass the error in the android API: when a menu item is selected, an event is logged and titleCondensed used to record the log. If titleCondensed not defined, it uses title and EventLog.writeEvent fails when formatting the string to the log.

So, we pass the unformed CharSequence in the consendedTitle workaround.

+4
Nov 05 '13 at 4:04
source share

Tested and works like a charm :)

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

Custom class span

 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); } } 
+2
Mar 01 '17 at 13:53 on
source share

I think Android does not support customization for the options menu. But you can try another way: http://www.codeproject.com/Articles/173121/Android-Menus-My-Way
Thus, the menu item is actually a text image and an image, so you can easily change the font, color ...

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

+1
Jul 07 2018-12-12T00:
source share

None of the answers above worked for me. I achieved this by completing the following solution:

 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; } 
+1
Aug 11 '17 at 17:15
source share

The only solution I found was to create a custom dialog that appears when you click the menu button. The layout will be like this:

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

After that, from the Activity class in the OnOptionsItemSelected method, I will write the following code:

 @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); } } 
0
Apr 14 '14 at 15:09
source share



All Articles