Can I disable ActionBar's navigation Spinner?
android, android-actionbar
Solution
Yes, it is possible to disable the `Spinner` used in list navigation in `ActionBar`. But is't not a straightforward solution, rather a hack. ActionBar doesn't provide a direct access to the `Spinner` view. Unfortunately the `Spinner` 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 proper `Spinner`. Since the `Spinner` 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 of `Spinner` (`IcsSpinner` does not extend from `Spinner`).
private View findActionBarSpinner() {
View rootView = findViewById(android.R.id.content).getRootView();
List<View> spinners = traverseViewChildren( (ViewGroup) rootView );
return findListNavigationSpinner(spinners); // implement according to your layouts
}
private List<View> traverseViewChildren(ViewGroup parent) {
List<View> spinners = new ArrayList<View>();
for (int i = 0; i < parent.getChildCount(); i++) {
View child = parent.getChildAt(i);
if (child instanceof Spinner) {
spinners.add( child );
} else if (child instanceof IcsSpinner) { // add this if you are using ActionBarSherlock
spinners.add( child );
} else if (child instanceof ViewGroup) {
spinners.addAll( traverseViewChildren( (ViewGroup) child ) );
}
}
return spinners;
}
The function `findListNavigationSpinner` should be implemented in a way that you are able to distinguish the other spinners. If you are not using any `Spinner` (or any view derived from it), the returned list should contain just one item.
The code above describes how to get the `Spinner` in an `Activity`. Naturally, it is not a problem to disable the `Spinner` from within a `Fragment`. The fragment has a reference to it's activity, so the activity can expose the code to the fragment via some interface.
Problem
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.