What I want to achieve is disabling all items on ActionBar except one. I have a custom ActionBar
with Menu
,several TextViews
, one Button
and a Spinner
from ListNavigation.
Spinner is created because of bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
like this :
SpinnerAdapter spinnerAdapter = new ArrayAdapter<String>(this.getActivity(), R.layout.action_bar_spinner, names);
// "listener" for spinner
bar.setListNavigationCallbacks(spinnerAdapter, new OnNavigationListener() {
@Override
public boolean onNavigationItemSelected(int position, long itemId) {
// do some stuff
return true;
}
});
I want to disable the Spinner
, so that it is inactive, but still visible with last item selected before disabling it.In short I need something like bar.getNavigationSpinner.setEnabled(false)
if it existed. Question is: Is there some kind of workaround ? If not, is there a way to disable whole ActionBar
,but keep it visible ?
Note: I want to achieve it in a Fragment.
This can be simplified by noting that the ActionBar (and Spinner) is between the root view and the content (with id == android.R.id.content). So you can implement a breadth-first search and return the first Spinner you find, no longer adding to the queue once you hit the view with id == android.R.id.content.
Or do the depth-first search, but stop recursing when you hit the view with id == android.R.id.content as the Spinner isn't contained in there.
So there's no need to maintain any list, just return the first Spinner found.
The above code does not work with Action Bar compat (v7 support library). I needed to enable/disable the action bar spinner of my app (API 2.2) using this support library but I have noticed that the name of the class is
SpinnerICS
insteadSpinner
.The full package name is
Because of this class is not visible and can not be imported in my code, I can not use:
So finally I solved my issue using
getClass().getName
. Therefore the code for enabling/disabling the spinner using Action Bar compat support library (v7) will be:Also, I have modified my findListNavigationSpinner method to check if the spinners list has elements to prevent
ArrayIndexOutOfBoundsException
. Because I only have one spinner in my app (in the Action Bar compat), so my code is this (you should adapt it if you would have more than one spinner):Yes, it is possible to disable the
Spinner
used in list navigation inActionBar
. But is't not a straightforward solution, rather a hack. ActionBar doesn't provide a direct access to theSpinner
view. Unfortunately theSpinner
is created in a private code without any id.So how to access the
Spinner
instance? One solution could be to access it via Java reflection API, but I wouldn't recommend that.A better solution is to get the root view for the current
Activity
, traverse it's child views (action bar and all it's views are present in the view hierarchy) and find the properSpinner
. Since theSpinner
in action bar is presumably the only one you haven't created yourself, you should be able to distinguish it from the others.Getting the root
View
is described in this SO question.The traversal is rather simple, just bear in mind that if you are using ActionBarSherlock, you have to look for
IcsSpinner
instead ofSpinner
(IcsSpinner
does not extend fromSpinner
).The function
findListNavigationSpinner
should be implemented in a way that you are able to distinguish the other spinners. If you are not using anySpinner
(or any view derived from it), the returned list should contain just one item.The code above describes how to get the
Spinner
in anActivity
. Naturally, it is not a problem to disable theSpinner
from within aFragment
. The fragment has a reference to it's activity, so the activity can expose the code to the fragment via some interface.