【发布时间】:2016-05-10 17:45:28
【问题描述】:
我有一个带有 NavigationView 和两个标签 a 和 b 的应用程序。导航视图中的两个MenuItems对应于Tab a和b @ @ a 987654327 @ 987654327,NavigationView MenuItem A应该选择,同样适用于MenuItem B。选择 MenuItem A 和 B 也应该相应地将选项卡更改为 a 和 b。此处选择意味着使用 selector 更改图标和文本的颜色,如下所示:
colors_navigationview.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="true"
android:color="@color/red"
android:drawable="@color/red" />
<item android:state_checked="false"
android:color="@color/gray"
android:drawable="@color/gray" />
</selector>
布局中的NavigationView定义:
<android.support.design.widget.NavigationView
android:id="@+id/my_navigationview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/my_navigationview_header"
app:menu="@menu/my_navigationview"
app:itemIconTint="@drawable/colors_navigationview"
app:itemTextColor="@drawable/colors_navigationview"
/>
MenuItems 包含在 SubMenu 中,定义如下:
my_navigationview.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_menu"
android:title="@string/foo">
<menu>
<item
android:id="@+id/my_navigationview_tab1"
android:icon="@drawable/fooicon"
android:title="@string/bar"/>
<item
android:id="@+id/my_navigationview_tab2"
android:icon="@drawable/baricon"
android:title="@string/barg"/>
</menu>
</item>
</menu>
问题是,在选择选项卡a或b,通过单击选项卡,或刷新选项卡的选项卡,MenuItems A和B s颜色没有更新。但是,直接在 NavigationView 中选择 MenuItems 是可行的,并且调用了完全相同的代码。因此,我有点困惑为什么这不起作用。
总结一下:
- 在 NavigationView 中选择 MenuItem 会设置正确的颜色并更改选项卡。一切正常。
- 选择选项卡会更改选项卡,但选择颜色没有更改。我认为 MenuItem 设置为选中,因为
MenuItem.setSelected(true)被调用。
我可以尝试什么来解决这个问题?我目前不知所措-这应该是IMO容易做的事情。我已经尝试了以下以及更多:
- 来自this问题的各种建议。
- 使各种 GUI 元素以及 NavigationView 和 DrawerLayout 无效。
我的Activity中的相关方法
@Override
public void onCreate()
{
// ...
// mTabLayout and mViewPager are created properly.
mTabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager)
{
@Override
public void onTabSelected(TabLayout.Tab tab)
{
super.onTabSelected(tab);
updateNavigationViewSelection();
}
});
}
@Override
public void onResume()
{
// ...
// To set correct NavigationView when resuming. Actually works ok at startup.
updateNavigationViewSelection();
}
public void updateNavigationViewSelection()
{
int currentItem = mViewPager.getCurrentItem();
selectNavigationMenuItem(currentItem);
}
public void selectNavigationMenuItem(int tab)
{
MenuItem menuItem = null;
NavigationView navigationView = (NavigationView) findViewById(R.id.my_navigationview);
switch (tab)
{
case TAB1:
menuItem = getNavigationMenuItemTab1();
break;
case TAB2:
menuItem = getNavigationMenuItemTab2();
break;
}
if (menuItem != null)
{
unselectAllNavigationMenuItems(); // Calls setChecked(false) on all MenuItems, may be commented out for testing.
// We arrive here, from onTabSelected(), onResume() and onNavigationItemSelected().
// onResume() sets the color correctly, as does onNavigationItemSelected(),
// but *not* when calling from onTabSelected(). All the values seem to be correct, but nothing happens.
// It seems that checked is set to true, but there is some invalidation missing.
// Invalidating NavigationView or DrawerLayout does nothing.
menuItem.setChecked(true);
}
}
@Override
public boolean onNavigationItemSelected(MenuItem menuItem)
{
switch (menuItem.getItemId())
{
case R.id.my_navigationview_tab1:
selectNavigationMenuItem(TAB1);
// Close drawer.
return true;
case R.id.my_navigationview_tab2:
selectNavigationMenuItem(TAB2);
// Close drawer.
return true;
default:
return false;
}
}
@Nullable
private MenuItem getNavigationMenuItemTab1()
{
MenuItem navigationMenu = getNavigationMenu();
return navigationMenu == null ? null : navigationMenu.getSubMenu().findItem(R.id.my_navigationview_tab1);
}
@Nullable
private MenuItem getNavigationMenuItemTab2()
{
MenuItem navigationMenu = getNavigationMenu();
return navigationMenu == null ? null : navigationMenu.getSubMenu().findItem(R.id.my_navigationview_tab2);
}
@Nullable
private MenuItem getNavigationMenu()
{
NavigationView navigationView = (NavigationView) findViewById(R.id.my_navigationview);
return navigationView == null ? null : navigationView.getMenu().findItem(R.id.navigation_menu);
}
private void unselectAllNavigationMenuItems()
{
MenuItem item;
item = getNavigationMenuItemTab1();
if (item != null)
item.setChecked(false);
item = getNavigationMenuItemTab2();
if (item != null)
item.setChecked(false);
}
【问题讨论】:
-
但两个菜单项都未选中?
-
NavigationView 有一个选择项目的方法,developer.android.com/intl/in/reference/android/support/design/… 你试过用它代替你当前的代码吗?
-
@Chris:在启动时,第一个 MenuItem 会从 onResume() 调用中被选中。此后,始终选择单个项目,但仅在从
selectNavigationMenuItem()调用时才更改。 @Luksprog 是的,我尝试使用setCheckedItem(),但我会仔细检查以确保。 -
我可以重现这个错误,并尝试了几种方法也不起作用。
-
好的,很高兴知道不是我有这个问题。仅供参考:使用
setCheckedItem()对我来说也没有任何改变。从ViewPager.OnPageChangeListener()调用updateNavigationViewSelection()没有区别,仅供参考。