【问题标题】:onNavigationItemSelected in ActionBar is being called at startup how can avoid it?ActionBar中的onNavigationItemSelected在启动时被调用如何避免它?
【发布时间】:2014-04-08 17:32:29
【问题描述】:

我正在使用带有下拉菜单的 ActionBar,并且在创建 Activity 后立即调用 onNavigationItemSelected(),因此调用了第一项。我的下拉菜单的第一项是 Home,与使用 android.R.id.home 按下应用程序图标的操作相同,因此当应用程序启动时它会调用自己。为了避免这种情况发生,我有这个代码:

if(this.getClass() != FrecView.class){  //if i am not currently on the Activity
    Intent frec = new Intent(this, FrecView.class);
    frec.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(frec);
}

但是我的所有活动都有 ActionBar,因此每次启动每个活动时,它都会永远调用自己,因此我必须为每个活动添加该代码。怎么了?我怎样才能防止这种情况发生?

【问题讨论】:

    标签: android android-actionbar


    【解决方案1】:

    正如 Mark 所说,它不是为菜单而设计的。

    但是,这是一种快速而肮脏的方法来忽略第一次调用:

    声明这个类字段:

    //mNaviFirstHit should be initialized to true
    private boolean mNaviFirstHit = true;
    

    并且在onNavigationItemSelected中:

    @Override
    public boolean onNavigationItemSelected(int itemPosition, long itemId) {
        if (mNaviFirstHit) {
            mNaviFirstHit = false;
            return true;
        }
        // DO WHAT YOU WOULD NORMALLY DO
    }
    

    【讨论】:

    • 私有布尔 mNaviFirstHit = false;不是 0。
    • 正确解决方案:(我也编辑了内容)mNaviFirstHit 应该初始化为 true 而不是 0 不是 false;
    【解决方案2】:

    我正在使用带有下拉菜单的 ActionBar,并且在创建 Activity 后立即调用 onNavigationItemSelected()

    这不是设计成“菜单”,就像标签被设计成“菜单”一样。列表导航旨在允许用户为当前活动指示一些内容,通常通过替换片段。操作项(例如,工具栏按钮、操作溢出区域)用于在活动之间导航。

    我的下拉菜单的第一项是 Home 与按下应用程序图标相同的操作 android.R.id.home 所以当应用程序启动时它会调用自己。

    所以,从您的“菜单”中删除它。用户可以按左侧的应用图标导航到主页。

    【讨论】:

    • 但是如果不把家放在那里它会调用我的一个活动,你说它不是为调用活动而设计的,所以我必须把所有的动作都放在 ActionBar 图标上?
    • @Andres:“但如果一个人不把家放在那里,它会调用我的一项活动”——不,会“调用一项[你的]活动”。 Spinner 总是有一个选择,无论是您选择的还是默认的第一个条目。如果您选择在第一个选择上开始活动,那是您自己的错,因为您是编写该代码的人。
    • “那是你自己的错”...也许它不是一个菜单,但它看起来和感觉完全一样。发生这种错误是有可能的。此外,包括 SO 在内的一些资源错误地建议了这种方法:stackoverflow.com/questions/13958912/…
    【解决方案3】:

    您可以使用以下命令在“菜单”中强制使用正确的默认选项:

    bar.setListNavigationCallbacks(mNavigationAdapter, this);
    bar.setSelectedNavigationItem(indexOfCurrentActivityInTheMenu);
    

    反直觉地,这必须在设置回调之后完成(在我看来,这会让回调有机会在导航索引为 0 的情况下触发)。例如,我的应用程序有两个活动 ListView 和 PageView,我喜欢按字母顺序排列的导航菜单,但默认启动活动是 PageView。所以我在 PageView 的 onCreate() 中有以下内容:

    bar.setListNavigationCallbacks(mNavigationAdapter, this);
    bar.setSelectedNavigationItem(1);
    

    在 ListView 的 onCreate() 中:

    bar.setListNavigationCallbacks(mNavigationAdapter, this);
    bar.setSelectedNavigationItem(0);
    

    那么,无论我调用多少次startActivity(otherView),它总是会正确设置导航菜单。

    【讨论】:

      【解决方案4】:

      首先感谢@CommonsWare 提醒我们它是选项卡的替代品,所以代码应该从这个角度来设计。虽然它不像看起来那么简单,但我们可以在那里解决。

      这也可以通过使用标志来避免。但是,无论如何我建议我采取的方法来解决这个问题。

      只要确保它被调用一次。 除此之外,使其成为内部类而不是匿名类。这将防止每次执行这部分代码时调用它。代码如下:

      if(localOnNavigationListener != null)
          localOnNavigationListener = new LocalOnNavigationListener();
      
      class LocalOnNavigationListener implements OnNavigationListener{
      
          @Override
          public boolean onNavigationItemSelected(int itemPosition, long itemId) {
          // do something
          return true;
        }
      
      }
      

      我在这里看到一个奇怪的事件,如果我将其设为内部类,它不会调用 onNavigationItemSelected(),如果我们将其设为匿名类,它将触发 onNavigationItemSelected 方法。如果有人能对此有所了解,那将很有用。

      【讨论】:

        猜你喜欢
        • 2011-10-17
        • 1970-01-01
        • 2022-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多