Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I disable ActionBar's navigation Spinner?

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.

like image 993
slezadav Avatar asked Feb 18 '23 12:02

slezadav


1 Answers

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.

like image 191
Tomik Avatar answered Feb 27 '23 05:02

Tomik