在没有虚拟项目或反射的情况下取消选中底部导航视图中的所有项目

dra*_*ity 5 android android-proguard bottomnavigationview

我正在尝试使用设计库中的 BottomNavigationView。一切正常,除了我希望每个导航项目都开始一个活动,因此我想取消选中导航中的所有项目,使它们看起来相同。我尝试了几种解决方案,其中大部分都不起作用,最后一个确实有效,但感觉很hacky。

首先我这样做:

ViewGroup nav = (ViewGroup) bottomNav;
for(int i=0; i < nav.getChildCount(); i++) {
    nav.getChildAt(i).setSelected(false);
}
Run Code Online (Sandbox Code Playgroud)

这似乎什么也没做。

然后我尝试:

int size = bottomNav.getMenu().size();
for (int i = 0; i < size; i++) {
    bottomNav.getMenu().getItem(i).setChecked(false);
}
Run Code Online (Sandbox Code Playgroud)

这仅检查了最后一项而不是第一项。

最后我尝试在菜单中添加一个虚拟项目并执行以下操作:

bottomNav.getMenu().findItem(R.id.dummmy_item).setChecked(true);
bottomNav.findViewById(R.id.dummmy_item).setVisibility(View.GONE);
Run Code Online (Sandbox Code Playgroud)

这几乎有效,但它隐藏了下面的标题,在我的情况下这对上下文很重要。

然后我找到了这个答案:https : //stackoverflow.com/a/41372325/4888701并编辑了我上面的解决方案以包含它。具体来说,我添加了 proguard 规则,我使用了那个确切的帮助器类并调用了该方法。它看起来正确,似乎有效。但对我来说感觉hacky,因为:

  1. 我正在使用一个虚拟菜单项来不允许检查任何可见的项目
  2. 它为应该是一个小的视觉修复添加了相当多的代码。
  3. 我之前读过,如果可能的话,应该避免反射。

有没有其他更简单的方法来实现这一点,或者这是我们当前版本的库中最好的方法?

(作为旁注,我想知道此解决方案中的 proguard 规则是否必要以及它的作用是什么?我对 proguard 一无所知,但该项目是从启用它的其他人那里继承的。)

Joe*_*Wee 6

经过大量的反复试验,这对我有用(使用 Kotlin)

(menu.getItem(i) as? MenuItemImpl)?.let {
    it.isExclusiveCheckable = false
    it.isChecked = it.itemId == actionId
    it.isExclusiveCheckable = true
}
Run Code Online (Sandbox Code Playgroud)


Nic*_*oso 1

如果我正确理解了你的问题(我可能没有),那么更好的解决方案可能是扭转这个问题。这些是我对你的问题的假设:

  • 您有一组活动
  • 每个 Activity 都有自己的 BottomNavigationView
  • 当您单击一项活动上的 BNV 时,单击的项目将被选中
  • 您想要取消选择单击的项目,因为当新活动启动时没有选择任何内容

如果我的假设是正确的,有两个更好的解决方案:

  1. 使用片段而不是活动(推荐
    • 当 BNV 停留在一项活动上时,活动中的片段会发生变化
  2. 不要取消选择单击的项目
    • 每个活动启动时都会选择正确的图块进行匹配

也就是说,如果您确实想按照自己的方式进行操作,我认为下面的代码将实现它,只需在受影响的项目发生变化时对其进行更改即可。(您应该尽可能避免反射,它通常表明您的设计存在另一个架构问题)

bnv.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
     @Override
     public boolean onNavigationItemSelected(@NonNull MenuItem item) {
         item.getActionView().setSelected(false);
         return false;
     }
});
Run Code Online (Sandbox Code Playgroud)