3

I would like to show a spinner in my ActionBar, using ActionBar.NAVIGATION_MODE_LIST, but I would like it to hide/show based on some application context. I have found that I can remove it from the ActionBar with getActionBar().setNavigationMode(-1), however I don't know if this is a good idea.

Any feedback on if this is safe or if there is a safer alternative?

ab11
  • 19,770
  • 42
  • 120
  • 207

3 Answers3

15

Maybe this is more accepted:

ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(false);
Scott W
  • 9,742
  • 2
  • 38
  • 53
  • the goal is display the navigation spinner, and then hide/show it as needed. this only shows it? – ab11 Jan 30 '13 at 22:10
  • 1
    @ab11: `setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD)` will remove the effects of `setNavigationMode(ActionBar.NAVIGATION_MODE_LIST)`. I do not quite know why the `setDisplayShowTitleEnabled(false)` is in the code snippet, though. – CommonsWare Jan 31 '13 at 00:44
  • My assumption was that @ab11 wanted to have a completely empty ActionBar (no title, no navigation). If the title should remain, then simply drop off the `setDisplayShowTitleEnabled(false)` – Scott W Jan 31 '13 at 14:35
  • Oh, I was also thrown by that but now understand. Thanks – ab11 Jan 31 '13 at 18:17
2

If you stick to ActionBar.NAVIGATION_MODE_LIST, you will have to set navigation listener every time you want to show your spinner back. That is obviously not the best soluton.

Instead, you may want to use ActionBar.setCustomView() to set spinner navigation (reference).

Here is some sample code where you set the spinner:

Spinner navigationSpinner = new Spinner(this);
navigationSpinner.setAdapter(yourSpinnerAdapter);
// Here you set navigation listener
navigationSpinner.setOnItemSelectedListener(yourSpinnerNavigationListener); 
getActionBar().setCustomView(navigationSpinner);
getActionBar().setDisplayShowCustomEnabled(true);

Then, when you want to show/hide it you simply change it's visibility:

getActionBar().getCustomView().setVisibility(View.INVISIBLE);
Vasily Sochinsky
  • 3,981
  • 2
  • 23
  • 20
0

Just modify your implementation of ActionBarDrawerToggle like this:

public void onDrawerSlide(View drawerView, float slideOffset) {
        super.onDrawerSlide(drawerView, slideOffset);
        if (slideOffset == 0) { // 0 = drawer is closed             
            setActionBarNavigationVisibility(activity, true); //show Tabs when Drawer is closed             
        }
    }

public void onDrawerStateChanged(int newState) {
        super.onDrawerStateChanged(newState);
        //hides Tabs right after Drawer starts opening
        if (DrawerLayout.STATE_DRAGGING == newState || DrawerLayout.STATE_SETTLING == newState) {
            setActionBarNavigationVisibility(activity, false);
        }
    }

Where method setActionBarNavigationVisibility is considering all navigation modes (you can delete code for unnecesarry navigation modes):

public static void setActionBarNavigationVisibility(Activity activity, boolean visible) {
    try {
        /* 1. --- If the navigation items are showing in ActionBar directly. We have 3 options Spinner, Tabs, and CustomNav ---
         (When Tabs are showing BELOW ActionBar, is handled at the end) */
        int actionViewResId = Resources.getSystem().getIdentifier("action_bar", "id", "android"); // @see http://stackoverflow.com/questions/20023483/how-to-get-actionbar-view
        View actionBarView = activity.findViewById(actionViewResId); // returns instance of com.android.internal.widget.ActionBarView (inaccessible)
        if (actionBarView != null) {
            int visibility = visible ? View.VISIBLE : View.INVISIBLE; // not GONE, so it still takes space in ActionBar layout

            // handle tabs navigation
            Field mTabScrollViewField = actionBarView.getClass().getDeclaredField("mTabScrollView");
            if (mTabScrollViewField != null) {
                mTabScrollViewField.setAccessible(true);
                View mTabScrollView = (View) mTabScrollViewField.get(actionBarView); // instance of com.android.internal.widget.ScrollingTabContainerView (inaccessible)
                if (mTabScrollView != null)
                    mTabScrollView.setVisibility(visibility);
            }

            // handle Spinner navigation
            Field mSpinnerField = actionBarView.getClass().getDeclaredField("mSpinner"); // resp. mListNavLayout
            if (mSpinnerField != null) {
                mSpinnerField.setAccessible(true);
                View mSpinner = (View) mSpinnerField.get(actionBarView); // instance of android.widget.Spinner
                if (mSpinner != null)
                    mSpinner.setVisibility(visibility);
            }

            // handle Custom navigation
            Field mCustomNavViewField = actionBarView.getClass().getDeclaredField("mCustomNavView"); // resp. mListNavLayout
            if (mCustomNavViewField != null) {
                mCustomNavViewField.setAccessible(true);
                View mCustomNavView = (View) mCustomNavViewField.get(actionBarView);
                if (mCustomNavView != null)
                    mCustomNavView.setVisibility(visibility);
            }
        }
        // 2. --- If the Tabs are BELOW ActionBar (narrow screens) ---          
        ViewParent actionBarContainer = actionBarView.getParent(); // parent of ActionBarView is com.android.internal.widget.ActionBarContainer (inaccessible)
        Field mTabContainerField = actionBarContainer.getClass().getDeclaredField("mTabContainer");
        if (mTabContainerField != null) {
            mTabContainerField.setAccessible(true);
            View mmTabContainer = (View) mTabContainerField.get(actionBarContainer);
            if (mmTabContainer != null)
                mmTabContainer.setVisibility(visible ? View.VISIBLE : View.GONE); // now use GONE, so the mTabContainer below Actionbar does not take space in layout
        }

    } catch (Exception ex) {
        // TODO Handle exception...         
    }
}
Štarke
  • 627
  • 6
  • 10