Выбор элемента NavigationView не обновляется при смене вкладки

У меня есть приложение с NavigationView и двумя вкладками a и b. Два элемента MenuItem в NavigationView соответствуют вкладке a и b, так что при выборе вкладки a должен быть выбран элемент меню NavigationView A, и то же самое для элемента MenuItem B. Выбор элемента меню 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"
    />

Элементы меню содержатся в подменю, определяемом следующим образом:

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, будь то непосредственное нажатие на вкладку или пролистывание ViewPager для вкладок, цвета элементов меню A и Bs не обновляются. > Однако выбор элементов меню непосредственно в NavigationView работает, и вызывается точно такой же код. Таким образом, я немного озадачен тем, почему это не работает.

Подвести итоги:

  1. Выбор MenuItem в NavigationView устанавливает правильный цвет и вкладку изменений. Все в порядке.
  2. Выбор вкладки меняет вкладку, но цвет выделения не изменяется. Я думаю, что для MenuItem установлено значение selected, так как вызывается MenuItem.setSelected(true) .

Что я могу попытаться исправить эту проблему? В настоящее время я в растерянности - это должно быть легко сделать ИМО. Я пробовал следующее и многое другое:

  1. Различные предложения из этого вопроса.
  2. Аннулирование различных элементов графического интерфейса, а также NavigationView и DrawerLayout.

Соответствующие методы в моей деятельности

@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);
}

person Krøllebølle    schedule 10.05.2016    source источник
comment
но оба пункта меню не выбраны?   -  person Chris Sherlock    schedule 10.05.2016
comment
NavigationView имеет метод для выбора элемента, developer.android.com/intl/in/reference/android/support/design/ вы пытались использовать его вместо текущего кода?   -  person user    schedule 10.05.2016
comment
@Chris: при запуске первый MenuItem выбирается из вызова onResume(). После этого всегда выбирается один элемент, но он изменяется только при вызове из selectNavigationMenuItem(). @Luksprog Да, я пытался использовать setCheckedItem(), но я дважды проверю это, чтобы убедиться.   -  person Krøllebølle    schedule 10.05.2016
comment
Я смог воспроизвести эту ошибку и попробовал несколько методов, которые тоже не сработали.   -  person Chris Sherlock    schedule 10.05.2016
comment
Хорошо, приятно знать, что эта проблема не у меня. Просто для справки: использование setCheckedItem() для меня тоже ничего не меняет. Не имеет значения вызов updateNavigationViewSelection() из ViewPager.OnPageChangeListener(), просто для справки.   -  person Krøllebølle    schedule 10.05.2016


Ответы (1)


Кажется, я нашел небольшой обходной путь.

Несколько методов вроде:

navigationView.getMenu().getItem(indx).setChecked(true);
navigationView.getMenu().findItem(someId).setChecked(true);
navigationView.setCheckedItem(someId);
navigationView.getMenu().performIdentifierAction(someId, 2);

не сработало. Но если вы инициируете событие, вызвав прослушиватель навигации

onNavigationItemSelected(MenuItem)

метод работает.

например в вашем приложении:

onNavigationItemSelected(getNavigationMenuItemTab1());
person Chris Sherlock    schedule 10.05.2016
comment
Какую версию вспомогательных библиотек вы использовали? Я сделал обновление с 23.1.0 до 23.3.0, и теперь оно работает как прелесть, как с использованием onNavigationItemSelected(), так и без него. Может быть, этот вызов исправляет проблему где-то в предыдущих библиотеках поддержки? - person Krøllebølle; 10.05.2016
comment
У меня самые последние библиотеки поддержки, но мне эти методы не подошли - person Chris Sherlock; 10.05.2016
comment
Это странно. Что ж, думаю, у нас есть работающее решение в любом случае. - person Krøllebølle; 10.05.2016