Currently, my options menu is aligned to the end of the screen. I want to give it a margin, something like android:layout_marginEnd = "20dp". How can I achieve this?
My options menu:
<?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"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item
android:id="#+id/menu_items"
android:icon="#drawable/menu_icon"
app:showAsAction="always">
<menu>
<group android:id="#+id/item1">
<item
android:id="#+id/download"
android:icon="#drawable/download_icon"
android:title="Download"></item>
</group>
<group android:id="#+id/item2">
<item
android:id="#+id/invite"
android:icon="#drawable/invite_icon"
android:title="Invite"></item>
</group>
</menu>
</item>
</menu>
My Custom Toolbar:
<androidx.appcompat.widget.Toolbar
android:id="#+id/menu_toolbar"
app:popupTheme="#style/ThemeOverlay.MyTheme"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_below="#id/greetText"> <!--assume it comes somewhere in the centre due to this-->
</androidx.appcompat.widget.Toolbar>
My Theme for menu items:
<style name="ThemeOverlay.MyTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="android:textColor">#color/dimGray</item>
<item name="android:textSize">14sp</item>
<item name="android:layout_marginEnd">20dp</item> <!-- doesn't work-->
<item name="android:fontFamily">#font/quicksand_medium</item>
<item name="android:background">#drawable/options_menu_background</item>
</style>
Here is the image of my problem. It shows how the end of the menu and the screen are aligned. I want space/margin between these two.
This is an interesting problem. I tried with many things found on the internet, but nothing works. I tried setting the actionOverflowMenuStyle with dropDownHorizontalOffset attribute which does not work either. Finally, I ended up getting a PopupMenu which works just fine. Here is the implementation.
Get your initial menu shorter with a single item which will open up the popup menu as a submenu.
<?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/menu_items"
android:icon="#drawable/ic_close_swipe"
android:title="#string/app_name"
app:showAsAction="always" />
</menu>
Then create another menu, in your /res/menu/ folder, named popup_menu.xml like the following.
<?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/menu_items"
android:icon="#drawable/ic_close_swipe"
android:title="#string/app_name"
app:showAsAction="always" />
</menu>
Now in your MainActivity, just add the following functions to handle the click action of the menu button and the popup menu.
public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar myToolbar = findViewById(R.id.menu_toolbar);
setSupportActionBar(myToolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_items:
showPopupMenu();
return true;
default:
return false;
}
}
public void showPopupMenu() {
PopupMenu popup = new PopupMenu(this, findViewById(R.id.menu_items));
popup.setOnMenuItemClickListener(this);
popup.inflate(R.menu.popup_menu);
popup.setGravity(Gravity.END);
Object menuHelper;
Class[] argTypes;
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popup);
argTypes = new Class[]{boolean.class};
menuHelper.getClass().getDeclaredMethod("setForceShowIcon", argTypes).invoke(menuHelper, true);
} catch (Exception e) {
e.printStackTrace();
}
popup.show();
}
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.invite:
Toast.makeText(this, "Invite", Toast.LENGTH_LONG).show();
return true;
case R.id.download:
Toast.makeText(this, "Download", Toast.LENGTH_LONG).show();
return true;
default:
return false;
}
}
}
I put the working code in this Github Branch. You might consider cloning from that branch and run the application to check if that suffices your expectation.
Hope that helps!
Related
When i long click on a recyclerview item the context menu shows but only the text, not the associated icons, here's the code:
<?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"
xmlns:tools="http://schemas.android.com/tools">
<item
android:id="#+id/bookmark"
android:orderInCategory="1"
android:title="#string/bookmarked_ayah"
android:icon="#drawable/ic_bookmark" />
<item
android:id="#+id/fbshare"
android:orderInCategory="2"
android:title="#string/fb_share"
android:icon="#drawable/ic_facebookshare" />
<item
android:id="#+id/saveayah"
android:orderInCategory="3"
android:title="#string/save_ayah"
android:icon="#drawable/ic_save" />
</menu>
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.ayah_saving_actionbar_items,menu);
return true;
}
If you're running your code on Android 3.0+, the icons in the menu are not shown by design. This is a design decision by Google.
But if you really want to show icons, you can use the code:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
try {
Field field = menu.getClass().getDeclaredField("mOptionalIconsVisible");
field.setAccessible(true);
field.setBoolean(menu, true);
} catch (Exception e) {
e.printStackTrace();
}
return super.onPrepareOptionsMenu(menu);
}
It uses reflection and sets the icons visible. I tested and here is the result:
I want to add 2 or 3 icons on action Bar in android app. I already took the empty activity and added the toolbar. I also set the Icon at left side. Now i want to add another two icons on it. But there is no Menu folder in my project directory structure. So any one tell me how i can do this all with proper guidelines?
My code is here :
My activity file
public class ActionBarActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_action_bar);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setIcon(R.drawable.left_nav);
getSupportActionBar().setTitle("");
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
my .xml file
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:fitsSystemWindows="true"
tools:context="firstapp.vaibhav.com.firstapp.ActionBarActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
Screen shot of my project directory structure
1. Create a menu folder in your existing resource res folder. (Ex. .../res/menu)
2. Create a main.xml file in menu folder. (Ex. .../res/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/action_item_one"
android:title="Camera"
android:icon="#drawable/ic_menu_camera"
app:showAsAction="always" />
<item
android:id="#+id/action_item_two"
android:title="Send"
android:icon="#drawable/ic_menu_send"
app:showAsAction="always" />
</menu>
3. In your activity, Override onCreateOptionsMenu() and onOptionsItemSelected() to work with option menus.
ActionBarActivity.java
#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);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_camera) {
// Do something
return true;
}
if (id == R.id.action_send) {
// Do something
return true;
}
return super.onOptionsItemSelected(item);
}
OUTPUT
Hope this will help~
create menu.xml with item like this
<?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_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />-->
<item
android:id="#+id/action_refresh"
android:orderInCategory="100"
app:showAsAction="always"
android:icon="#drawable/ic_action_autorenew"
android:title="Search"/>
<item
android:id="#+id/action_search"
android:orderInCategory="100"
app:showAsAction="always"
android:icon="#drawable/ic_action_search"
android:title="Search"/>
</menu>
and use it in activity
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// MenuInflater inflater1 = getActivity().getMenuInflater();
inflater.inflate(R.menu.cartmenu, menu);
return ;
}
in your res/menu/menu_main.xml:
add
<?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/icon_id"
android:visible="true"
android:title="#string/icon_name"
android:icon="#drawable/your_image"
app:showAsAction="always">
</item>
</menu>
in your activity:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
// return true so that the menu pop up is opened
return true;
}
To access your menu item in activity add:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.your_item_id) {
// your code
return true;
}
return super.onOptionsItemSelected(item);
}
You can use showAsAction option found at item in menu resource file.
1) If you want to add popup menu then write app:showAsAction="never"
2) If you want to add icons as an action (multiple icons in actionbar) then write app:showAsAction="always"
I need to inflate custom menu in Fragment.
I have only one menu item.But the icon is not displaying.
Can someone tell what is wrong with my code
My menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" >
<item
android:id="#+id/search"
android:icon="#android:drawable/ic_search_category_default"
app:showAsAction="always"
android:title="Search"/></menu>
And I set in onCreateView()
setHasOptionsMenu(true);
getActivity().invalidateOptionsMenu();
And inflating the menu
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Auto-generated method stub
inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.menu, menu);
}
Resulting screen attached below. I need to have the search icon instead of the menu overflow icon.
I know I'm a little late for the party, but hope I can help someone else. Today I was facing this SAME problem.
I fixed using android:showAsAction="always" instead of app:showAsAction="always"
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/bluetooth_status_off"
android:orderInCategory="0"
android:icon="#drawable/bluetooth_red"
android:title="#string/app_name"
android:showAsAction="always" />
</menu>
on the showAsAction is underlined with red (warning), but works fine.
I Think You should use
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" >
<item
android:id="#+id/search"
android:icon="#drawable/ic_search_category_default"
app:showAsAction="always"
android:title="Search"/></menu>
and
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.mymenu, menu);
return true;
}
Sorry to late but put this code in your onCreate()
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
You have to add the following property app:showAsAction="ifRoom"
Make sure, you've added a menu item without an icon.
Example:
<?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/next_btn"
android:checked="true"
android:icon="#android:drawable/ic_input_add"
android:title="Item"
app:showAsAction="ifRoom" />
<item
android:id="#+id/action_settings"
android:title="Settings" />
</menu>
Thanks to action_settings, it'll automatically add an overflow icon.
make a menu with the code below...
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="#string/action_settings"/>
<item
android:id="#+id/action_search"
android:title="Search"
android:icon="#android:drawable/ic_menu_search"
android:showAsAction="always"
android:actionViewClass="android.widget.SearchView" />
</menu>
and set it as your menu..
This is default behaviour of the Overflow menu from the ActionBar.
If you want to show the Icons in the overflow menu, override the onMenuOpened method in your activity with this code snippit:
#Override
public boolean onMenuOpened(int featureId, Menu menu) {
if(featureId == Window.FEATURE_ACTION_BAR && menu != null){
if(menu.getClass().getSimpleName().equals("MenuBuilder")){
try{
Method m = menu.getClass().getDeclaredMethod(
"setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, true);
}
catch(NoSuchMethodException e){
Log.e("MyActivity", "onMenuOpened", e);
}
catch(Exception e){
throw new RuntimeException(e);
}
}
}
return super.onMenuOpened(featureId, menu);
}
If you're running your code on Android 3.0+, the icons in the menu are not shown by design.
This is a design decision by Google.
You can read more about this on Android developers blog.
Copy your menu xml code.
Delete your menu file
Now create a new menu file in res->menu directory
And name it with different name
Now Run
I'm trying to highlight menu item title when it is selected in action bar and display its corresponding view in a fragment below. Fragment loading is working good but I'm not able to style menu items when they are clicked.
What I would like to have is something like below mentioned methods-
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// item.setSiblingsStyle(R.style.passive_menu_item);
// item.setStyle(R.style.active_menu_item);
}
Is it possible to style menu title in "onOptionsItemSelected" method? Please help !
You could try to use selector definition:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
<item android:state_pressed="true" android:color="#color/blue_light"/> <!-- pressed -->
<item android:state_enabled="false" android:color="#color/grey_cloud"/> <!-- focused -->
<item android:color="#color/black"/> <!-- default -->
</selector>
I've figured using just text is not a good way. So I decide to add icons and use state of items to toggle by maintaining few variables. Here is an implementation:
private current_selected_menu;
private main_menu;
public void updateMenuState(){
if (main_menu==null){
return;
}
int sz = main_menu.size();
for(int i=0;i<sz;i++){
if(main_menu.getItem(i).getItemId()==current_selected_menu){
main_menu.getItem(i).setEnabled(false);
}
else{
main_menu.getItem(i).setEnabled(true);
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.sample_menu, menu);
current_selected_menu = menu.getItem(0).getItemId(); // I'm using first item as enabled by default
main_menu = menu;
int sz = menu.size();
for(int i=0;i<sz;i++){
if(menu.getItem(i).getItemId()==current_selected_menu){
menu.getItem(i).setEnabled(false);
}
else{
menu.getItem(i).setEnabled(true);
}
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item1:
// Do something
current_selected_menu = item.getItemId();
updateMenuState();
return true;
case R.id.item2:
// Do something
current_selected_menu = item.getItemId();
updateMenuState();
return true;
default:
// Do Something
return super.onOptionsItemSelected(item);
}
}
As suggested by Xingchen, One can use selectors to define multiple icons. Below is a sample implementation:
icon_selector.xml file in res/drawable:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/icon_passive" android:state_enabled="false"/>
<item android:drawable="#drawable/icon_active" android:state_enabled="true"/>
</selector>
Note: icon_passive.png and icon_active.png are two image files used as icons.
sample_menu.xml file in res/menu:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu1" android:icon="#drawable/icon_selector" android:title="menu1" android:showAsAction="always|withText" android:visible="true"></item>
<item android:id="#+id/menu2" android:icon="#drawable/icon_selector" android:title="menu2" android:showAsAction="always|withText" android:visible="true"></item>
<item android:id="#+id/menu3" android:icon="#drawable/icon_selector" android:title="menu3" android:showAsAction="always|withText" android:visible="true"></item>
</menu>
I feel there could be better ways than above mentioned. I'll keep this open. Please feel free to suggest better solutions or better practices : )
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.
JAVA Code-:
#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-:
<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.
Create Style in styles.xml
<style name="Style_TextView">
<item name="fontFamily">#font/myriadproregular</item>
</style>
Add Below code into android.support.design.widget.NavigationView
app:itemTextAppearance="#style/Style_TextView"
Note: It works for android.support.design.widget.NavigationView
you have to provide a custom layout for the menu item.
First, in your menu XML set one of the following
CASE 1 if you are using the support library:
<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 2 if you are not using the support library:
<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:
<?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:
<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:
<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>
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>
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);
}
You can also use a SpannableStringBuilder when you add a menu item with a TypefaceSpan. For each menu item do something like
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);
If your app only needs to work on Android Pie (API level 28) and above you can construct a TypefaceSpan from a Typeface in onPrepareOptionsMenu. Otherwise you can use a CustomTypefaceSpan class like this answer suggests:
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 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:
I found this solution is usefull for me .hope it will help full new surfers.
your menu 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
res/drawable folder.
#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;
}
Simply set itemTextAppearance property of the NavigationView to system or custom style:
<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"/>
The answer by #brahmyadigopula works well.
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);
If you are using android.support.design library then:
In theme:
app:itemTextAppearance="#style/bottom_navigation_textappreance"
if you are using Material design then:
In XML:
app:itemTextAppearanceActive="#style/bottom_navigation_textappreance"
app:itemTextAppearanceInactive="#style/bottom_navigation_textappreance"
In theme:
<style name="bottom_navigation_textappreance" parent="Widget.Design.BottomNavigationView">
<item name="fontFamily">#font/fira_sans_bold</item>
</style>