How to change the position of menu items on actionbar

42,916

Solution 1

I assume you are setting your custom view as a custom view in the action bar. If you are using ActionbarSherlock you can instead add the custom view as a normal menu item and set an action view for it using .setActionView(yourCustomView or yourCustomLayoutId). You can then set .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS) to display the view. Just make sure your custom view is set to width wrap_content or otherwise it will push the other menu items off the screen. This might also work without ActionbarSherlock, but I haven't tried it there yet.

EDIT: Try modifying your onCreateOptionsMenu method

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.websearch_menu, menu);

    // add this
    menu.add(Menu.NONE, 0, Menu.NONE, "custom")
        .setActionView(R.layout.header)
        .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);

    return true;
}

and remove this from your onCreate method

actionBar.setDisplayShowCustomEnabled(true);
cView = getLayoutInflater().inflate(R.layout.header, null);
actionBar.setCustomView(cView);

EDIT:

If you need to reference the views from your custom layout, you can do this in your onCreateOptionsMenu method as follows (note: I wrote this code in the browser, so no guarantee that I didn't make a typo or something):

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // inflate the menu and add the item with id viewId,
    // which has your layout as actionview

    View actionView = menu.getItem(viewId).getActionView();
    View viewFromMyLayout = actionView.findViewById(R.id.viewFromMyLayout);

    // here you can set listeners to your view or store a reference 
    // to it somewhere, so you can use it later

    return true;
}

Solution 2

Just use orderInCategory in your xml file and it will order from less number to greater (from left side of your action bar). Such as:

<item
    android:id="@+id/Refresh"
    android:icon="@drawable/ic_action_refresh"
    android:showAsAction="ifRoom"
    android:title="@string/refresh"
    android:orderInCategory="2"/>
<item
    android:id="@+id/Search"
    android:icon="@drawable/ic_action_action_search"
    android:showAsAction="ifRoom|collapseActionView"
    android:title="@string/search"
    android:orderInCategory="1"/>

Even though, Refresh item is coming first in xml file, it won't be first. But Search icon from left to rigth in your action bar will be first according to its orderInCategory attribute.

Solution 3

The order of the menu items will be set according to their order in the XML file that they are inflated.

Therefore all you need to do is change the order in the XML file as you like.

Share:
42,916
Anupam
Author by

Anupam

Android Developer

Updated on January 13, 2020

Comments

  • Anupam
    Anupam over 4 years

    I'm developing one application in which I have to add a custom layout on actionbar. Adding the custom layout is done, but when I'm adding the menu items on actionbar my custom layout changes it's position from right of the actionbar to center of the actionbar. Below is the image what I have achieved so far.

    Done till here

    I want something like this on the actionbar.

    Like this

    Custom layout(yellow button) at the right most part of actionbar and menu items in the middle.

    Adding my code to achieve this custom layout using native android actionbar:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);
    
        actionBar = getActionBar();
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setDisplayUseLogoEnabled(false);
        actionBar.setDisplayHomeAsUpEnabled(false);
        actionBar.setDisplayShowCustomEnabled(true);
        cView = getLayoutInflater().inflate(R.layout.header, null);
        actionBar.setCustomView(cView);
    
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.websearch_menu, menu);
        return true;
    
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    
        switch (item.getItemId()) {
    
        case android.R.id.home:
            finish();
    
        default:
            return super.onOptionsItemSelected(item);
        }
    }
    

    How can this be achieved?

    Any kind of help will be appreciated.

  • Anupam
    Anupam about 11 years
    Can you guide me how to achieve this? Any sort of code will be help for me.
  • Thrakbad
    Thrakbad about 11 years
    I have added the code how to do this with ActionbarSherlock, I hope it is the same with the default Actionbar
  • Anupam
    Anupam about 11 years
    You rocked dude. Thank you so much, you saved me from creating a complete custom layout and then inflating it to the actionbar. Thanx!
  • android developer
    android developer about 11 years
    @Thrakbad How does it change the order of the items on the actionBar exactly? I don't understand.
  • Anupam
    Anupam about 11 years
    @Thrakbad Can we give some margin from left to the menu item, so that, it completely be in the middle of the actionbar?
  • Thrakbad
    Thrakbad about 11 years
    @androiddeveloper The items are just added from left to right, so the item added last will be the one to the right (except for the overflow menu)
  • Thrakbad
    Thrakbad about 11 years
    @Anupam I think this would only be possible with a complete custom layout
  • android developer
    android developer about 11 years
    Yes, wherever you wish to change the order of the items, save the configuration of the order of the items, and call invalidateOptionMenu() . Then , in the onCreateOptionsMenu() method, check the configurations you've stored, and using a loop, go over all of the items you wish to insert by their order , and add them to the menu one by one, dynamically. You should do it by accessing the "menu" variable of onCreateOptionsMenu(). If you wish to contain "static" action items using inflate, that's ok, just find exactly where to put the rest inside the menu itself.
  • android developer
    android developer about 11 years
    @Thrakbad This is interesting. How do you use your own custom layout for the action bar? is it this "actionBar.setCustomView(cView);" ?
  • Thrakbad
    Thrakbad about 11 years
    That is one option, if you set a custom view with the width match_parent and add no menu items you will have your custom view over the whole action bar. Another solution is to add only one menu item and set the custom view as its actionView much like I did in the example above.
  • android developer
    android developer about 11 years
    @Thrakbad Cool. Thanks. Good to know. Hope I will remember this when I need it.
  • Mahdi
    Mahdi over 9 years
    @Thrakbad how we can get the items in that cutom layout for functioning?
  • Thrakbad
    Thrakbad over 9 years
    Just add listeners etc in your onCreateOptionsMenu method or store a (weak) reference to the View there to be used later
  • Mahdi
    Mahdi over 9 years
    but how? evem when I add OnClick method in header.xml file app crash and says can't find method.
  • Thrakbad
    Thrakbad over 9 years
    Ah, sorry I didn't understand your question correctly. You can't use XML, you have to do it in your code. See my second edit above.