90

I have an action bar in my app with 3 items.

Only 2 can be displayed due to space issues, so I'd expect the first to be displayed and the rest to be displayed in the overflow. However in practice only the first 2 items are shown and there is no overflow detectable.

Here is the relevant code: list_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/menu_insert"
    android:icon="@android:drawable/ic_menu_add"
    android:title="@string/menu_insert" 
    android:showAsAction="ifRoom|withText"/>
<item android:id="@+id/menu_call"
    android:icon="@android:drawable/ic_menu_call"
    android:title="@string/menu_call" 
    android:showAsAction="ifRoom|withText"/>
<item android:id="@+id/menu_agenda"
    android:icon="@android:drawable/ic_menu_agenda"
    android:title="@string/menu_agenda" 
    android:showAsAction="ifRoom|withText"/>
</menu>

Activity.java

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater mi = getMenuInflater();
    mi.inflate(R.menu.list_menu, menu);
    return true;
}
Mel
  • 5,837
  • 10
  • 37
  • 42
Mats Raemen
  • 1,781
  • 1
  • 28
  • 41
  • 120
    If your device has a menu-button, the overflow-icon won't show. What device are you on? – Reinier Mar 16 '12 at 15:12
  • 1
    the virtual device i'm testing on has a menu button indeed, clicked it and the missing item showed up, thanks! – Mats Raemen Mar 16 '12 at 15:48
  • 2
    @Reinier I'm using ActionBarSherlock. On Galaxy Ace running 2.3 it is shown, on Galaxy SII running 4.0 it is not shown. Both have HW menu button. – Mister Smith Oct 26 '12 at 11:26
  • 2
    I wanted to confirm that this had me baffled that I had the overflow icon on a nexus 7 buy not on Galaxy Note II. The Note had a menu button. Thanks! – bsautner Jul 26 '13 at 17:10
  • @Reinier please help i facing the same issue what should i do? – rupesh Dec 30 '13 at 16:35
  • Just make sure that your settings in the android manifest have entry like this one android:theme="@android:style/Theme.WithActionBar" – Ajay George May 28 '14 at 07:34
  • @Reinier Kind of senseless that it only shows on devices without a menu button. What if the menu button on a device stopped working? Maybe Google should enable the overflow button regardless whether the device has a menu button or not. – Johann Jul 26 '14 at 13:53
  • @Reinier your comment should have been an answer.. – Sindri Þór Feb 16 '16 at 18:16
  • Is this issue API related or Device related ?! – Basheer AL-MOMANI Apr 03 '16 at 18:19

9 Answers9

125

If you want to show the three dots, irrespective of device menu button! then you can call this method in your application class' onCreate method-

private void makeActionOverflowMenuShown() {
    //devices with hardware menu button (e.g. Samsung Note) don't show action overflow menu
    try {
        ViewConfiguration config = ViewConfiguration.get(this);
        Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
        if (menuKeyField != null) {
            menuKeyField.setAccessible(true);
            menuKeyField.setBoolean(config, false);
        }
    } catch (Exception e) {
        Log.d(TAG, e.getLocalizedMessage());
    }
}
Paul Verest
  • 60,022
  • 51
  • 208
  • 332
Atul Kaushik
  • 5,181
  • 3
  • 29
  • 36
  • 33
    This is an awful hack that breaks consistency with the rest of the apps on the platform. Do not do this. – adamp Jan 10 '13 at 18:12
  • 19
    This seems like the lesser of two evils. The current behavior is unacceptable. – biorbnA Mar 28 '13 at 03:00
  • I'm new to Android, and quite appalled that this hack is necessary :-(. However, I see no alternative but to use it! Many thanks to @Kaushik for revealing it :-). – Stochastically Apr 17 '13 at 22:30
  • 6
    It's a great way to allow to have overflow, the menu hard key should no longer be tolerated. – Necronet May 05 '13 at 23:18
  • 1
    This is awesome thank you, however it doesn't seem to work on 2.3.5 :-( – Darren May 16 '13 at 13:34
  • 5
    It works great! Works even if user press the hardware menu button (which is brilliant), though you will hear the menu sound effect twice.. does anyone know how to make it only sound once? – Bruce Nov 13 '13 at 02:36
  • 5
    THIS IS NOT A HACK. Devs need to know what to be calling hacks as it's just not 2+2 in Android. Reflection is saving time using Java mechanisms, or else you would be passing contexts to your inner classes 24/7, or customizing AOSP to infinity. To me this solution solves the problem of having to override and include tons of AOSP custom content AND linked, private associations just for the sake of what purists consider clean. Did you know you can't force FASTSCROLL enabled consistently for small lists? Before I used reflection, this required me to copy 10+ AOSP resources, for a ONE char edit. – leRobot Apr 01 '14 at 16:32
  • @Darren it doesn't work because in 2.3.5 everything that is not an ActionView will be passed to the old school menu, showing up at the bottom of the screen. Man I miss thumb-reachable buttons and menus on phones... – leRobot Apr 02 '14 at 19:18
  • 1
    @leRobot of course it's a hack. Using reflection to access non-public fields is always a hack because it might or might not work depending on whether a framework developer decides to do some internal refactoring (or not). It's also a hack because device manufacturer decide whether they want a hardware menu button or not and users of these devices will get used to whatever they have. Showing the overflow button on a device with a hardware menu button is a waste of space. Also it's about consistency of all apps on a single device not about consistency of an app across devices. – Emanuel Moecklin Mar 24 '15 at 14:16
  • Well, it is open for debate. I personally do whatever I want with my apps. You have this (mostly) open API with tons of features that could still be implemented from scratch if so desired, and still create apps for every device. Using the APIs built-in implementation of that feature, you get restrictions due to their internal policy. That policy is not mine. AOSP stands for (...) open source (...). So, to me there are only 2 POVs: it's a hack for Google employees who are told it's not good practice (or consider Google a religion); or this is just old school programming – leRobot Mar 24 '15 at 14:44
  • 1
    Even Google doesn't wholesale believe that the hardware menu button behaviour is correct. Chrome displays overflow on an S3, and so does Keep. This is nonsensical behaviour which is forcing everyone to use hacks - including Google (Chrome overflow on an S3 doesn't behave like Keep overflow). It's just down to which hack you find least offensive. – David Sainty Oct 27 '15 at 06:39
54

Output

Action Bar

res/menu/menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- Search / will display always -->
    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_action_search"
        android:showAsAction="always"
        android:title="@string/action_search"/>

    <!-- Location Found -->
    <item
        android:id="@+id/action_location_found"
        android:icon="@drawable/ic_action_location_found"
        android:showAsAction="always"
        android:title="@string/action_location_found"/>

    <!-- More -->
    <item
        android:id="@+id/a_More"
        android:icon="@drawable/ic_action_overflow"
        android:showAsAction="always"
        android:title="More">
        <menu>

            <!-- Refresh -->
            <item
                android:id="@+id/action_refresh"
                android:icon="@drawable/ic_action_refresh"
                android:showAsAction="never"
                android:title="@string/action_refresh"/>

            <!-- Help -->
            <item
                android:id="@+id/action_help"
                android:icon="@drawable/ic_action_help"
                android:showAsAction="never"
                android:title="@string/action_help"/>

            <!-- Check updates -->
            <item
                android:id="@+id/action_check_updates"
                android:icon="@drawable/ic_action_refresh"
                android:showAsAction="never"
                android:title="@string/action_check_updates"/>
        </menu>
    </item>

</menu>

MainActivity.java

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
  
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
 
        return super.onCreateOptionsMenu(menu);
    }

}

Download the Action Bar Icon Set

Kirit Vaghela
  • 12,572
  • 4
  • 76
  • 80
42

I realize this is not an overflow menu, but it is similar. Okay, this is simple but was hard to figure out.

You first need a menu item you want to use as the overflow inflater. Example

<item
        android:id="@+id/a_More"
        android:icon="@drawable/more"
        android:showAsAction="always"
        android:title="More">
        </item>

Once you have your item, add a sub-menu containing your items you want in the overflow menu. Example:

<item
    android:id="@+id/a_More"
    android:icon="@drawable/more"
    android:showAsAction="always"
    android:title="More">
    <menu>
        <item
            android:id="@+id/aM_Home"
            android:icon="@drawable/home"
            android:title="Home"/>
    </menu>
</item>

On click this will inflate other items within. My application is using ActionBarSherlock 4.0 so before this will work for you, you will need to access the "SplitActionBar". (Will still work on default android Actionbar)

Here's how: In your AndroidManifest.xml file, you need to add this code under the activity you need the overflow menu in.

android:uiOptions="splitActionBarWhenNarrow"

NOTE: Your item that inflates your overflow menu MUST showAsAction="always"

Vwola! you have an overflow menu! Hope I helped you out. :)

LeviRockerSk8er
  • 661
  • 7
  • 8
26

On devices with hardware menu buttons (Galaxy S3, stubborn as Samsung is...) the overflow menu behaves as the 'traditional' menu, by using the hardware menu button.

Lukas Batteau
  • 2,473
  • 1
  • 24
  • 16
  • 2
    Old answer, however with compatibility library just stumble across very odd results: 3 devices with hardware button, Note 3 Neo = Overflow menu is shown, menu button doesn't work, Note 1 = No overflow, menu button works, Galaxy S3, no overflow, menu button doesn't work! This is crazy. – 3c71 Nov 08 '14 at 19:27
5

To alway show action overflow (three dot) on actionbarcompat:
in menu file, example:
main.xml

<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:title="@string/action_settings"
        app:showAsAction="never"/>
    <item
        android:id="@+id/action_about"
        android:title="@string/action_about"
        app:showAsAction="never"/>

</menu>

and in activity file:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return super.onCreateOptionsMenu(menu);
}

It's worked fine for me.
Tested on Google Nexus S, Samsung S3.

MrSiro
  • 281
  • 1
  • 4
  • 16
5

When you say "overflow" menu, do you mean the three dots that show up in the end to indicate that there are more items.... or do you mean the split actionbar that shows up in the bottom for overflow items?

If you mean the split action bar, you should add this to your activity's manifest file

android:uiOptions="splitActionBarWhenNarrow"

By default, the three dots overflow menu should happen automatically, so it's hard to tell what the problem is from the information you provided above.

wnafee
  • 2,126
  • 16
  • 23
  • I do mean the three dots. It's not like it's because of the items, because whenever changing items of order, it's the first 2 icons that are shown – Mats Raemen Mar 16 '12 at 14:58
  • should I provide extra information to be able to determine the actual problem? – Mats Raemen Mar 16 '12 at 15:10
  • What are your minSdkVersion, targetSdkVersion, and the version you are testing on? – Sparky Mar 16 '12 at 15:20
  • 5
    Does your device have physical buttons for menu or are they virtual buttons like the galaxy nexus phone? I think the three dots will only show up if your phone doesn't have physical buttons. – wnafee Mar 16 '12 at 15:30
3

It appears that on devices with a menu button the overflow menu does not show in the ActionBar. Also we have no way to know if a device has a hardware menu button before API level 14 (4.0+).

This solution adds a overflow button to a android.support.v7.app.ActionBar that opens the standard options menu on pre-Honeycomb (<3.0) only, otherwise leaving it to the system. In any case you can choose between always or ifRoom for all actions.

Get the overflow icon from the Action Bar Icon Pack.

Add a menu (I'omitting some non-relevant parts as titles, ordering etc.)

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">

<item
    android:id="@+id/action_overflow"
    android:orderInCategory="100"
    android:icon="@drawable/ic_action_overflow"
    app:showAsAction="always" />

<item
    android:id="@+id/action_first"
    app:showAsAction="always" />

<item
    android:id="@+id/action_second"
    app:showAsAction="ifRoom" />

</menu>

Remove our overflow action on 3.0+

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        menu.removeItem(R.id.action_overflow);
    }
    return super.onPrepareOptionsMenu(menu);
}

Finally call Activity.openOptionsMenu() from the overflow action.

Er... no. You cannot not call openOptionsMenu() from a menu button... but if you are using AndroidAnnotations you're done easily:

@OptionsItem
void action_overflow() {
    openOptionsMenuDeferred();
}

@UiThread
void openOptionsMenuDeferred() {
    openOptionsMenu();
}

If not you should do something like this, I suppose

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == id.action_overflow) {
        openOptionsMenuDeferred();
        return true;
    }
}

private Handler handler = new Handler(Looper.getMainLooper());
public void openOptionsMenuDeferred() {
    handler.post(new Runnable() {
        @Override
        public void run() {
            openOptionsMenu();
        }
    }
    );
}
IlDan
  • 6,851
  • 3
  • 33
  • 34
2

Put xmlns:your_app_name="http://schemas.android.com/apk/res-auto" inside menu tag and instead android:showAsAction="always" use your_app_name:showAsAction="always"

for eg

<item
    android:id="@+id/action_search"
    android:icon="@drawable/icon_search"
    android:title="@string/search"
    your_app_name:showAsAction="ifRoom"/>

Remees M Syde
  • 2,564
  • 1
  • 19
  • 42
Rashmi Jain
  • 343
  • 2
  • 10
2

Try changing the theme of the app from Theme.AppCompat.Light.DarkActionBar to Theme.AppCompat.Light

Sagar Devanga
  • 2,815
  • 27
  • 30