13

I'm developing for android 3+

In my action bar i have a drop-down list(see how to hide/unhide the actionbar list on android 3? for the dropdown i intend). The problem is i need to do a certain action when the user selects something, but Android calls onNavigationItemSelected() as soons as it draws the view, so no selection actually happened.

How can i detect if the user actually pressed something and it is not a fake call from android ?

public class ListDittaListener implements OnNavigationListener{

    private BaseActivity activity;

    private ListDittaListener()
    {

    }

    public ListDittaListener(BaseActivity activity)
    {
        this.activity = activity;
    }

    @Override
    public boolean onNavigationItemSelected(int itemPosition, long itemId)
    {
        MyApp appState = ((MyApp)this.activity.getApplicationContext());
        appState.setDittaSelezionata( (int) itemId);

        SharedPreferences settings = this.activity.getSharedPreferences(MyApp.PREFS_NAME, 0);
        SharedPreferences.Editor editor = settings.edit();
        editor.putInt("ditta_id_selezionata", (int) itemId);

            ////////restart activity this.activity.recreate();

        return false;
    }

}
Community
  • 1
  • 1
max4ever
  • 11,909
  • 13
  • 77
  • 115

5 Answers5

16

You can easily just ignore the first call to onNavigationItemSelected if you like:

public class Whatever implements OnNavigationListener {
    private boolean synthetic = true;

    @Override
    public boolean onNavigationItemSelected(int itemPosition, long itemId) {
        if (synthetic) {
            synthetic = false;
            return true;
        }

        // do whatever you really wanted here 
    }
}
mlc
  • 1,668
  • 2
  • 16
  • 30
  • 1
    thanks but like i wrote in the bounty description, "i would like to avoid using a counter and ignoring the first call", this seems more like a hack, i would like to get to understand why this happends in the first place – max4ever Mar 14 '12 at 08:15
  • 3
    I have the same issue and it's terribly annoying to hack it this way. Is there a purpose for such a behavior? – Michał Klimczak Aug 15 '12 at 21:51
  • I used this solution to prevent Fragments from needlessly being re-created twice when the screen orientation changes and losing their state. See [here](http://stackoverflow.com/a/14295474/963396). – XåpplI'-I0llwlg'I - Jan 12 '13 at 17:24
  • If you ignore the first call, there will not be subsequent calls when you select items in the dropdown. – IgorGanapolsky Feb 03 '13 at 15:44
  • If you ignore first call, there's no second call with the same index – Marcos Vasconcelos Feb 06 '13 at 20:12
4

Method onNavigationItemSelected(int itemPosition, long itemId) will be called anyway by the action bar.

What you may want to do is to tell action bar what itemPosition it should pass to the method on the first call. (In other words, to tell action bar what navigation item should be set after activity is created). Here is the code:

mActionBarMenuSpinnerAdapter = ...;
mActionBar = getActionBar();
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
mActionBar.setListNavigationCallbacks(mActionBarMenuSpinnerAdapter, this);
mActionBar.setSelectedNavigationItem(###your_default_navigation_item_here###);

After doing this you can solve your problem by applying changes in the onNavigationItemSelected(int itemPosition, long itemId) if only itemPosition is different.

GregoryK
  • 3,011
  • 1
  • 27
  • 26
2

The android system will call onNavigationItemSelected(0, 0) after the activity is setup. (Which means later than onResume()).

As other guys mentioned, you'd better not do any hack like ignore first call, otherwise the android system won't call onNavigationItemSelected() again when you select the first index. (The system thought the first item is already selected)

My solution is call actionbar.setSelectedNavigationItem(the real item# you want) after you setup the actionbar. Then the system will call onNavigationItemSelected() twice. First onNavigationItemSelected(0, 0) and then the onNavigationItemSelected(the real item#).

Wei Jiang
  • 196
  • 1
  • 8
  • At first you've said, it's better not to ignore first call, but what do you do when `onNavigationItemSelected(0, 0)` is called? – skywall Sep 14 '14 at 22:00
0

I have viewpager with fragments and I need set custom action bar for every fragment in pager In desired page I have navigation list, fragment fires onNavigationItemSelected automatically when I swipe pages, want to avoid this behavior and run tasks only if I selected nav item manually.

public class MyFragment extends Fragment implements ActionBar.OnNavigationListener {

    private boolead fireReady = false;

     @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        // every time make it false, this method invoked on swipe action
        fireReady = false; 

        if (isVisibleToUser) {
            // setup actionbar, you also can setup action bar in activity
            String[] array = getActivity().getResources().getStringArray(R.array.users_order);
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item, array);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

            getActivity().getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
            getActivity().getActionBar().setListNavigationCallbacks(adapter, this);
        }

    }

     @Override
    public boolean onNavigationItemSelected(int itemPosition, long itemId) {

        if (fireReady) {
            // task fire only when you directly press navigation item
            UsersTask task = new UsersTask(getActivity());
            task.setTaskListener(this);
            task.execute(usersUrls[itemPosition]);
        } else {
            // make it true first time when page displayed
            fireReady = true;
        }
        return false;
    }

}

}
biniam
  • 8,099
  • 9
  • 49
  • 58
Georgy Gobozov
  • 13,633
  • 8
  • 72
  • 78
0

Well I cannot see anything wrong in your current code.

How did you create your dropdown elements. And what element is "select" by Android after the view is created. And what are your doing in your onCreate method where the ActionBar is initialized.

I did it as instructed here and it worked for me: http://developer.android.com/guide/topics/ui/actionbar.html#Dropdown

Moritz
  • 266
  • 1
  • 8
  • it "selects" the first item of the dropdown element, onCreate i usually just call the code from the other linked question(basically just action_bar.setNavigationMode and action_bar.setListNavigationCallbacks) – max4ever Mar 07 '12 at 10:05
  • Mhh on point of view you are doing everything correct. Are you rotating your screen? I found a similar issue here: http://stackoverflow.com/questions/9039045/how-to-set-active-item-in-the-action-bar-drop-down-navigation – Moritz Mar 07 '12 at 12:40