【问题标题】:android action bar onNavigationItemSelectedandroid操作栏onNavigationItemSelected
【发布时间】:2012-03-01 14:16:39
【问题描述】:

我正在为 android 3+ 开发

在我的操作栏中,我有一个下拉列表(请参阅how to hide/unhide the actionbar list on android 3? 了解我想要的下拉列表)。问题是当用户选择某些内容时我需要执行某个操作,但 Android 在绘制视图后立即调用 onNavigationItemSelected(),因此实际上没有发生任何选择。

我如何检测用户是否真的按下了某些东西并且它不是来自 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;
    }

}

【问题讨论】:

    标签: android android-actionbar


    【解决方案1】:

    如果您愿意,您可以轻松忽略对onNavigationItemSelected 的第一次调用:

    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 
        }
    }
    

    【讨论】:

    • 谢谢,但就像我在赏金描述中写的那样,“我想避免使用计数器并忽略第一次调用”,这似乎更像是一个黑客,我想了解为什么会这样一开始就发生了
    • 我也有同样的问题,用这种方式破解它非常烦人。这种行为有目的吗?
    • 我使用这个解决方案来防止 Fragments 在屏幕方向改变并失去其状态时被不必要地重新创建两次。见here
    • 如果忽略第一次调用,则在下拉选择项目时不会有后续调用。
    • 如果忽略第一次调用,则没有第二次调用相同的索引
    【解决方案2】:

    方法onNavigationItemSelected(int itemPosition, long itemId) 无论如何都会被操作栏调用。

    您可能想要做的是告诉操作栏itemPosition 它应该在第一次调用时传递给方法。 (换句话说,告诉操作栏在创建活动后应该设置什么导航项)。代码如下:

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

    完成此操作后,如果只有 itemPosition 不同,您可以通过在 onNavigationItemSelected(int itemPosition, long itemId) 中应用更改来解决您的问题。

    【讨论】:

      【解决方案3】:

      Activity 设置完成后,android 系统会调用 onNavigationItemSelected(0, 0)。 (这意味着晚于 onResume())。

      正如其他人提到的,你最好不要做任何hack,比如忽略第一次调用,否则android系统不会在你选择第一个索引时再次调用onNavigationItemSelected()。 (系统认为第一项已经被选中)

      我的解决方案是在设置操作栏后调用 actionbar.setSelectedNavigationItem(您想要的真实项目#)。然后系统会调用两次 onNavigationItemSelected()。首先是onNavigationItemSelected(0, 0),然后是onNavigationItemSelected(真正的item#)。

      【讨论】:

      • 一开始你说过,第一次调用最好不要忽略,但是当onNavigationItemSelected(0, 0)被调用时你会怎么做?
      【解决方案4】:

      嗯,我看不出你当前的代码有什么问题。

      您是如何创建下拉元素的。在创建视图后,Android 会“选择”什么元素。你在初始化 ActionBar 的 onCreate 方法中做了什么。

      我按照这里的指示做了,它对我有用: http://developer.android.com/guide/topics/ui/actionbar.html#Dropdown

      【讨论】:

      • 它“选择”下拉元素的第一项,onCreate 我通常只是从另一个链接问题中调用代码(基本上只是 action_bar.setNavigationMode 和 action_bar.setListNavigationCallbacks)
      • 嗯,从观点来看,你做的一切都是正确的。你在旋转屏幕吗?我在这里发现了一个类似的问题:stackoverflow.com/questions/9039045/…
      【解决方案5】:

      我有带有片段的 viewpager,我需要为 pager 中的每个片段设置自定义操作栏 在所需的页面中,我有导航列表,当我滑动页面时,片段会自动触发 onNavigationItemSelected,希望避免这种行为并仅在我手动选择导航项时运行任务。

      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;
          }
      
      }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-29
        • 2014-04-16
        • 2014-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多