Reputation: 3028
I have an app with a NavigationView and two tabs a
and b
. Two MenuItems in the NavigationView correspond to tab a
and b
so that, when tab a
is selected, NavigationView MenuItem A
should be selected, and the same for MenuItem B
. Selecting MenuItem A
and B
should also change tab to a
and b
correspondingly. Selected here means changing the colors of the icon and text using a selector
like this:
<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>
<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"
/>
The MenuItems are contained in a SubMenu, defined like this:
<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>
The problem is that, when selecting tab a
or b
, be it by clicking the tabs directly or swiping the ViewPager for the tabs, the MenuItems A
and B
s colors are not updated. Selecting the MenuItems directly in the NavigationView works, however, and the exact same code is called. Thus I am a bit baffled as to why this does not work.
To summarize:
MenuItem.setSelected(true)
is called.What can I try to fix this issue? I am currently at a loss - this should be an easy thing to do IMO. I have tried the following and more:
@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);
}
Upvotes: 1
Views: 1452
Reputation: 941
Seems like i found a little workaround.
Several methods in like :
navigationView.getMenu().getItem(indx).setChecked(true);
navigationView.getMenu().findItem(someId).setChecked(true);
navigationView.setCheckedItem(someId);
navigationView.getMenu().performIdentifierAction(someId, 2);
did not work. But if you trigger the event by calling the navigation listener
onNavigationItemSelected(MenuItem)
method it works.
e.g. in your app:
onNavigationItemSelected(getNavigationMenuItemTab1());
Upvotes: 2