Force overflow menu in ActionBarSherlock

北慕城南 提交于 2019-12-17 02:30:58

问题


I want the 4.0+ overflow menu to be used on pre ICS devices (2.3 - 2.1). I'm using HoloEverywhere with ActionBarSherlock.

I tried the following solution:

ActionBarSherlock & HoloEverywhere - Forcing Overflow?

but it does not work because absForceOverflow does not exist. Was it removed in the newest version or something? I've checked the R files of both ABS and HE library projects and the field is simply not there.

My app's theme is set to @style/Holo.Theme.Sherlock.Light and that is the theme that i was trying to inherit from and add the absForceOverflow parameter set to true.


回答1:


If you are using Version 4.2.0, then .ForceOverflow themes have in fact been removed.

Source: Version 4.2.0 Changelog

Extract of the Change Log:

Add SearchView widget for standard search interaction (API 8+ only)
Fix: ShareActionProvider in the split action bar no longer fills the entire screen.
Fix: ShareActionProvider now does file I/O on a background thread.
Fix: Automatically correct ColorDrawable not respecting bounds when used as a stacked background.
Fix: Ensure fragments collection is present before dispatching events.
Fix: XML-defined onClick searches the correct context for the declared method.
Fix: Ensure action mode start/finish callbacks are invoked on the activity for the native action bar.
Fix: Allow tab callbacks to have a fragment transaction instance for any FragmentActivity.
Fix: Ensure CollapsibleActionView callbacks are dispatched in both native and compatbility action bars.
Fix: Remove .ForceOverflow themes. These never should have been included.

If you absolutely need to force Overflow, you will need to download an earlier version of ABS. You can get a list of download as per their release history here: http://actionbarsherlock.com/download.html

I personally still use the ABS version 4.1.0 since I do not currently want to make ancillary changes in my app. I also use this in my theme.xml:

<style name="MyTheme" parent="@style/Theme.Sherlock.ForceOverflow">
    <item name="android:windowBackground">@color/background</item>
    <item name="actionBarStyle">@style/Widget.Styled.ActionBar</item>
    <item name="android:actionBarStyle">@style/Widget.Styled.ActionBar</item>
</style>

<style name="MyTheme.ForceOverflow">
    <item name="absForceOverflow">true</item>
</style>

And while applying a theme for an Activity in the manifest.xml, I use this as the attribute: "@style/Theme.SociallyYOU"

Again, if you must absolutely force overflow, you might also want to read CommonsWare's thought on the same in another question here: https://stackoverflow.com/a/12872537/450534.

NOTE: That being said, it is always better to use the latest version if the trade offs aren't to critical. By posting how I force the overflow menu, I am neither suggesting that you use an older version nor do I recommend that. It is merely informing you of the possibilities.




回答2:


Beginning from ActionbarSherlock 4.2 we've lost the ability to manage overflow menu visibility. To make it working, you need combine 2 approaches:

  1. To force menu visibility for Android 3.x (honeycomb) and upper, you need use this hack + add check Android version:

    public static final int DEVICE_VERSION   = Build.VERSION.SDK_INT;
    public static final int DEVICE_HONEYCOMB = Build.VERSION_CODES.HONEYCOMB;
    if (DEVICE_VERSION >= DEVICE_HONEYCOMB)
        // Code from answer above
    
  2. Open menu for pre-honeycomb devices:

    • Open ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java, go to method reserveOverflow
    • Replace the original with:

      public static boolean reserveOverflow(Context context) { return true; }

    This will force menu showing ...

    • but when click on menu button menu popup not showing. To achieve this we need override this in your activity class:

      @Override
      public boolean onKeyUp(int keyCode, KeyEvent event) {
          if (DEVICE_VERSION < DEVICE_HONEYCOMB) {
              if (event.getAction() == KeyEvent.ACTION_UP &&
                  keyCode == KeyEvent.KEYCODE_MENU) {
                  openOptionsMenu();
                  return true;
              }
          }
          return super.onKeyUp(keyCode, event);
      }
      

After this actions you should have absolutely working overflow action bar menu for all Android versions.




回答3:


As Siddharth Lele has pointed out, it has been removed in the last ABS version in order to behave the same as the actual Action Bar. So at a first glance giving up on showing this menu is the best option.

However, the overflow menu showing in screen for some devices and not showing for others is a big design flaw in Android's Action Bar in my opinion. Here's why:

In devices with a hardware menu key, the menu won't show in the action bar. The tendency in most recent devices is to reduce the number of HW buttons to the minimum, since it is considered more user-friendly (and because iphones don't have but a button, so they copy this design). Other manufacturers do include the menu button but it's hidden unless you press over it (yes, it lights up when you no longer need the light. Not a wise design but again, when all the buttons are off the phone looks more iphonish).

To better understand the implications of this, let's see an example: User A has a device with menu key. He's using his favourite mail client. The options to configure mail accounts are placed in the overflow menu, along with the usual options(help, about, etc). He would like to add a second account but he doesn't have a clue on how to get to this menu. There's no info on screen to help him realize what to do. So user A asks his friend B, who is also using this mail client. User B has the latest Nexus N+1 Googlephone, and he's able to view the overflow icon in the action bar because his device doesn't sport a HW menu key. He shows A how he can add a 2nd account by opening this menu. User A is now totally confused, since they are using the same app versions. Frustated, A might think the problem is in his phone for being too old. B is also confused as well.

At this point you might be thinking both A and B are fools who can't figure how to use an smartphone. But unlike desktop apps, a great majority of smartphone users don't know but the basics about their devices. Their previous phone might well have been a keypad device with a simple firmware. The battery died and they went to the store for a replace, but it was out of stock. They could have ordered one in the internet but it was more expensive than buying a newer phone. So they were sold a touchscreen-enabled phone because that's how phones are nowadays. Now they have to face an small computer with a full-fledged OS. To make things worse, the phone comes only with a "quick start guide", and to get the full manual they have to download a pdf from the internet. Guess what? They won't.

If you are developing a mobile app you should assume the user might not know a thing about computers, the OS, or similar apps. You should make the GUI look similar across devices, so that people can learn and remember how to use it. Don't blame on Action Bar designers: if users like A or B don't know how to go to the options menu it's your fault in the first place. That's why you should have included a means of getting to options screen always visible.

Something similar happens with the back key. Some devices might have a HW back key, newer ones usually don't. But whenever we can go back in our apps we're always displaying that arrow-like button in the Action Bar, right? And yes, I know one button navigates back in the "navigation tree" while the other goes "back in time", but this is also another design flaw: for the mean user, back is just back. He has this button in the screen and he can also use the HW one, but this is optional. The same should have been done with the overflow menu.

So if you think (like me) that this is an important button, don't give up. Provide a regular main options menu and populate it with the pertinent submenus. Make it an action button and assign it a descriptive icon, or even a textual description like "MENU". You can also mimic the overflow menu icon, just use one of these drawables:

    // For ActionBarSherlock
    abs__ic_menu_moreoverflow_normal_holo_dark.png
    abs__ic_menu_moreoverflow_normal_holo_light.png

    // For ActionBar
    ic_menu_moreoverflow_normal_holo_light.png
    ic_menu_moreoverflow_normal_holo_dark.png

Moreover: go and copy-paste the images to your project res folder. You can never know whether future releases of ABS or the next implementation of ActionBar will include them.




回答4:


I find Exterminator13’s answer doesn't work on some kind of Android devices(The total number I think is quite small), but to fit for as much devices as possible, I uses dialog and use one menu with android:showAsAction="always" as overflow menu button.After all, the effect of overflow menu of actionbarsherlock is realized by its source, so why not realize the effect by our self if it is not so troublesome. If you understand Chinese,You can also see my blog.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/more"
        android:icon="@drawable/overflow"
        android:showAsAction="always" 
    />
</menu>

 

private Dialog popupDialog;
private Boolean popupState=false;

    public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case android.R.id.home:
        this.finish();
        return true;
    case R.id.more:
        if (!popupState) {
            showPop();
        }else {
            popupDialog.dismiss();
        }
    default:
        return super.onOptionsItemSelected(item);
    }
}

private void showPop(){
    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(ResID, null);
    ListView listView = (ListView) view.findViewById(ResID);
    listView.setAdapter(yourOwnAdapter);
    popupDialog = new Dialog(WifiAuthWireActivity.this);
    popupDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    popupDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.WHITE));
    popupDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    popupDialog.setContentView(view);
    // Calculate ActionBar height
    TypedValue tv = new TypedValue();
    ActionBar maActionBar=getSupportActionBar();
    int actionBarHeight=maActionBar.getHeight();
    if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
    {
        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
    }
    WindowManager.LayoutParams wmlp = popupDialog.getWindow().getAttributes();
    wmlp.gravity = Gravity.TOP | Gravity.RIGHT;
    wmlp.x+=12;
    wmlp.y+=actionBarHeight;
    popupDialog.getWindow().setAttributes(wmlp);
    popupDialog.show();
}


来源:https://stackoverflow.com/questions/13179620/force-overflow-menu-in-actionbarsherlock

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!