Как отключить режим сдвига BottomNavigationView?

BottomNavigationView не отображает заголовок меню, которые неактивны.

Как показать названия всех элементов меню в bottomNavigationBar? Проблема в том, что в моем случае показан только заголовок элемента, который нажат.

введите описание изображения здесь

11 Solutions collect form web for “Как отключить режим сдвига BottomNavigationView?”

Реализация BottomNavigationView имеет условие: при использовании более трех элементов используется режим сдвига.

В настоящий момент вы не можете изменить его через существующий API, и единственный способ отключить режим сдвига – использовать reflection.

Вам понадобится вспомогательный class:

 import android.support.design.internal.BottomNavigationItemView; import android.support.design.internal.BottomNavigationMenuView; import android.support.design.widget.BottomNavigationView; import android.util.Log; import java.lang.reflect.Field; public class BottomNavigationViewHelper { public static void disableShiftMode(BottomNavigationView view) { BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0); try { Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode"); shiftingMode.setAccessible(true); shiftingMode.setBoolean(menuView, false); shiftingMode.setAccessible(false); for (int i = 0; i < menuView.getChildCount(); i++) { BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i); //noinspection RestrictedApi item.setShiftingMode(false); // set once again checked value, so view will be updated //noinspection RestrictedApi item.setChecked(item.getItemData().isChecked()); } } catch (NoSuchFieldException e) { Log.e("BNVHelper", "Unable to get shift mode field", e); } catch (IllegalAccessException e) { Log.e("BNVHelper", "Unable to change value of shift mode", e); } } } 

А затем примените метод disableShiftMode в вашем BottomNavigationView , но помните, если вы раздуваете представление меню из своего кода, вы должны выполнить его после раздувания.

Пример использования:

 BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation_bar); BottomNavigationViewHelper.disableShiftMode(bottomNavigationView); 

PS.

Помните, что вам нужно будет выполнять этот метод каждый раз, когда вы меняете элементы меню в вашем BottomNavigationView .

ОБНОВИТЬ

Вам также необходимо обновить файл конфигурации proguard (например, proguard-rules.pro), код выше использует reflection и не будет работать, если proguard mShiftingMode поле mShiftingMode .

 -keepclassmembers class android.support.design.internal.BottomNavigationMenuView { boolean mShiftingMode; } 

Спасибо Мухаммаду Альфаифи за то, что он указал на эту проблему и предоставил fragment .

ОБНОВЛЕНИЕ 2

28.0.1-alpha1 отметила, что новая библиотека поддержки ( 28.0.1-alpha1 ), а также новая библиотека материалов ( 1.0.0-beta01 ) предлагает публичное свойство, которое можно использовать для управления режимом переключения в 3 элементах меню.

  

В библиотеке Material Components она также применяется, если имеется 5 пунктов меню.

Чтобы отключить текстовую анимацию, вы также можете использовать ее в файле dimens.xml:

 12sp 

Ответ Пшемыслава в Котлине как функция расширения

 @SuppressLint("RestrictedApi") fun BottomNavigationView.disableShiftMode() { val menuView = getChildAt(0) as BottomNavigationMenuView try { val shiftingMode = menuView::class.java.getDeclaredField("mShiftingMode") shiftingMode.isAccessible = true shiftingMode.setBoolean(menuView, false) shiftingMode.isAccessible = false for (i in 0 until menuView.childCount) { val item = menuView.getChildAt(i) as BottomNavigationItemView item.setShiftingMode(false) // set once again checked value, so view will be updated item.setChecked(item.itemData.isChecked) } } catch (e: NoSuchFieldException) { Log.e(TAG, "Unable to get shift mode field", e) } catch (e: IllegalStateException) { Log.e(TAG, "Unable to change value of shift mode", e) } } 

Использование (с расширениями Android Kotlin):

 bottom_navigation_view.disableShiftMode() 

Поскольку библиотека поддержки 28.0.0-alpha1:

  

Теперь вы можете использовать приложение: labelVisibilityMode = “[помечено, немеченое, выбранное, авто]” в 28-альфа

эти метки будут отображаться на всех ярлыках.

unabeled покажет только значки.

выбранный будет отображать только ярлык для выбранного элемента и сдвинуть элементы.

auto выберет маркировку или выбранную в зависимости от количества элементов, которые у вас есть. помечены для 1-3 предметов и выбраны для 3 предметов.

Чтобы отключить текстовую анимацию и уменьшить размер шрифта, используйте это в файле dimens.xml:

 10sp 10sp 

У меня было какое-то странное поведение с BottomNavigationView. Когда я выбирал в нем какой-либо элемент / fragment, fragment подталкивает BottomNavigationView немного ниже, поэтому текст BottomNavigationView идет под экраном, поэтому отображаются только значки и текст скрывается при нажатии любого элемента.

Если вы сталкиваетесь с этим странным поведением, то вот решение. Просто удалите

 android:fitsSystemWindows="true" 

в корневой компоновке fragmentа. Просто удалите это и бум! BottomNavigationView будет работать нормально, теперь его можно показать с текстом и значком. У меня это было в моем корневом координаторе.

Также не забудьте добавить

 BottomNavigationViewHelper.disableShiftMode(bottomNavigationView); 

в вашей деятельности, чтобы отключить режим переключения. Хотя это не совсем связано с заданным вопросом, но все же я считаю это полезным.

Это сторонняя библиотека, которую я использую, и она имеет множество параметров настройки, таких как отключение режима сдвига, отображение только значков, установка размера значков и т. Д. BottomNavigationViewEx

Работает на меня

 bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED); 

Чтобы полностью удалить анимацию:

Если вы также хотите избавиться от этой раздражающей анимации с малым максимальным показателем, вам нужно больше кода отражения. Вот полное решение, которое удаляет любую анимацию:

 @SuppressLint("RestrictedApi") private static void disableShiftMode(BottomNavigationView view) { BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0); try { Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode"); shiftingMode.setAccessible(true); shiftingMode.setBoolean(menuView, false); shiftingMode.setAccessible(false); for (int i = 0; i < menuView.getChildCount(); i++) { BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i); item.setShiftingMode(false); Field shiftAmount = item.getClass().getDeclaredField("mShiftAmount"); shiftAmount.setAccessible(true); shiftAmount.setInt(item, 0); shiftAmount.setAccessible(false); item.setChecked(item.getItemData().isChecked()); } } catch (NoSuchFieldException e) { Timber.e(e, "Unable to get fields"); } catch (IllegalAccessException e) { Timber.e(e, "Unable to change values"); } } 

И обязательно добавьте это в свой конфигурационный файл proguard:

 -keepclassmembers class android.support.design.internal.BottomNavigationMenuView { boolean mShiftingMode; } -keepclassmembers class android.support.design.internal.BottomNavigationItemView { int mShiftAmount; } 

просто хочу добавить, что выше этого метода disableShiftMode добавить ниже код тоже. @SuppressLint ( “RestrictedApi”)

Interesting Posts

Дессериализация XML для объектов в C #

Как написать asynchronous метод с параметром out?

Как уменьшить размер системы Windows 8?

Как передать значение с одной jsp на другую страницу jsp?

Что такое сценарий отладки DOS для низкоуровневого формата жесткого диска?

Явная специализация в области пространства имен (дубликат)

Почему смешивание деклараций и кода запрещено до C99?

Есть ли случай, когда полезно использовать ссылку RValue Reference (&&)?

Как вы затушевываете цвет фона с помощью jquery?

Управление запуском команд командной строки Windows в новом окне

Практические подходы CAPTCHA на основе изображений, не основанные на имидже?

Перегрузка конструктора в Java – лучшая практика

Запуск цикла – но подождите, пока строка слов в файле журнала продолжит

Linux shell, сохранить задачу в течение определенного времени

Должны ли мы переключиться на использование асинхронного ввода-вывода по умолчанию?

Давайте будем гением компьютера.