我在这里写的是关于我们从AppCompat库迁移到AndroidX库时引入的一个问题。在迁移过程中,我们从 android.support.design.widget.NavigationView
到 com.google.android.material.navigation.NavigationView
而这时,下面的问题就开始了。
在我们的NavigationView设计中,为了节省空间,我们实现了一个可展开的菜单,当用户点击 "更多 "按钮时,菜单会展开,显示更多的选项。一开始只有部分选项可见,其余的都不可见,如下图。
点击 "更多...... "按钮后,菜单会展开。
要做到这一点,我们使用了以下代码。
@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上得到的。乍一看,我并没有变得更聪明。我发现 导航视图 拥有 导航菜单展示器 对象字段 presenter
),该方法有一个叫做 updateMenuView() 其中调用 适配器.update(),这就要求 准备菜单项目() 和 notifyDataSetChanged()
. 这听起来像是需要解决的问题,所以使用反射,我们访问并调用了 updateMenuView()
方法,但出乎意料的是,这并没有什么用!所以,我决定把它做到极致,看看如果我调用这个方法会发生什么。
所以,我决定把它做到极致,看看如果我调用了 getMenu().clear()
不管你信不信,什么都没发生。似乎任何对菜单的改变 之后 的 NavigationView
显示,都被忽略了。但是翻看源码,我看不出任何原因。
那我该如何解决这个问题呢?我试着使用最新的alpha版本的库,但还是有同样的问题。
好吧,经过一番努力,我找到了解决方案。其实很简单。请稍等一下答案。
Lionscribe
所以我又回到了源代码中,寻找一些线索,当我发现一个叫做 setUpdateSuspended(boolean updateSuspended). 嗯,这听起来很可疑! 我搜索了一下这个方法的用法,发现它在 点击时 回调。这里是代码的最小化版本。
@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);
}
Bingo! 似乎在处理点击的时候,这个 NavigationView
暂停并不承认对菜单的任何更改。我不知道这是什么原因,但是当我们在更新菜单的时候,在 onNavigationItemSelected
回调,它由 onClick
方法,菜单更新被忽略。
好吧,当我理解了这个问题之后,解决方法就简单而干净了。我只是把代码封装在一个 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;
}
Viola! 可扩展菜单现在可以像以前一样工作了,隐藏的项目现在被显示出来了!我希望这能帮助其他人解决同样的问题。
我希望这对有同样问题的人有帮助。
Lionscribe