【问题标题】:NavigationView menu does not updateNavigationView 菜单不更新
【发布时间】:2020-06-08 01:18:43
【问题描述】:

我在这里写的是当我们从 AppCompat 库迁移到 AndroidX 库时引入的一个问题。在此过程中,我们从android.support.design.widget.NavigationView 切换到com.google.android.material.navigation.NavigationView,这就是以下问题的开始。

在我们的 NavigationView 设计中,为了节省空间,我们实现了一个可展开的菜单,这样当用户点击“更多”按钮时,菜单会展开以显示更多选项。一开始只有部分选项可见,其余选项不可见,如下;


  • 选项 1
  • 选项 2
  • 更多……

点击“更多...”按钮后,菜单展开为;


  • 选项 1
  • 选项 2
  • 选项 3
  • 选项 4
  • 选项 5
  • 选项 6

为此,我们使用了以下代码;

@Override
public boolean onNavigationItemSelected(MenuItem item)
{
    ....
    if (item.getItemId() == R.id.nav_more)
    {
        item.setVisible(false); // hide the “More” item
        getMenu().findItem(R.id.nav_option_3).setVisible(true);
        getMenu().findItem(R.id.nav_option_4).setVisible(true);
        getMenu().findItem(R.id.nav_option_5).setVisible(true);
        getMenu().findItem(R.id.nav_option_6).setVisible(true);
        return true;
    }
    .......
    return false;
}

好吧,这段代码在过去是有效的,但是当我们迁移到使用 androidx 库时,噗,它停止了工作。嗯,它确实有点作用。 “更多...”按钮被隐藏,但之前隐藏的选项并没有显示出来。 因为,我花了好几个小时才解决这个问题,为了避免其他人头疼,我将解释问题和解决方案。

在这种情况下,首先要做的是查看源代码。由于代码是开源的,我可以在 github 上获得它。乍一看,我并没有变得更聪明。我发现NavigationView 有一个NavigationMenuPresenter 对象字段(称为presenter),它有一个称为updateMenuView() 的方法,它调用adapter.update(),它调用prepareMenuItems()notifyDataSetChanged()。这听起来像是需要修复,所以使用反射,我们访问并调用了updateMenuView() 方法,但令人惊讶的是,它没有帮助!

所以,我决定把它发挥到极致,看看如果我打电话给getMenu().clear() 会发生什么,信不信由你,什么也没发生。似乎在显示NavigationView 之后 对菜单所做的任何更改都将被忽略。但是快速浏览一下源代码,我看不出有什么原因。

那么我该如何解决这个问题呢?我尝试使用该库的最新 alpha 版本,但仍然遇到同样的问题。

好吧,经过大量工作,我找到了解决方案。其实很简单。等待答案。

读狮

【问题讨论】:

    标签: android navigation-drawer android-navigation android-navigationview


    【解决方案1】:

    所以我回到源代码,寻找一些线索,然后我发现了一个名为setUpdateSuspended(boolean updateSuspended) 的方法。嗯,听起来很可疑!我搜索了这个方法的用法,发现它在onClick 回调中被调用。这是代码的最小化版本;

    @Override
        public void onClick(View view) {
          NavigationMenuItemView itemView = (NavigationMenuItemView) view;
          setUpdateSuspended(true);
          MenuItemImpl item = itemView.getItemData();
          boolean result = menu.performItemAction(item, NavigationMenuPresenter.this, 0);
          setUpdateSuspended(false);
      }
    

    宾果!似乎在处理点击时,NavigationView 暂停并且不会识别对菜单所做的任何更改。我不确定这是什么原因,但当我们在 onClick 方法调用的 onNavigationItemSelected 回调中更新菜单时,菜单更新被忽略了。

    好吧,一旦我理解了这个问题,解决方案就简单明了。我只是将代码包装在Runnable 中,然后发布它,以便它在onClick 方法返回之后运行,并将setUpdateSuspended 设置回false。这是更新的代码;

    @Override
    public boolean onNavigationItemSelected(MenuItem item)
    {
        ....
        if (item.getItemId() == R.id.nav_more)
        {
            final MenuItem itemFinal = item;
            post(new Runnable()
            {
                @Override
                public void run()
                {
                        getMenu().findItem(R.id.nav_option_3).setVisible(true);
                        getMenu().findItem(R.id.nav_option_4).setVisible(true);
                        getMenu().findItem(R.id.nav_option_5).setVisible(true);
                        getMenu().findItem(R.id.nav_option_6).setVisible(true);
                        itemFinal.setVisible(false);  // hide the “More” item
                }
            });
            return true;
        }
        .......
        return false;
    }
    

    维奥拉!可扩展菜单现在可以像以前一样工作了,现在显示隐藏的项目!

    我希望这对其他有同样问题的人有所帮助。

    狮王

    【讨论】:

    • Big tnx 分享此信息,对我帮助很大。 Tnx ;]
    猜你喜欢
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 2019-08-13
    • 1970-01-01
    • 2019-03-22
    • 2015-10-10
    • 1970-01-01
    相关资源
    最近更新 更多