Как отключить режим сдвига BottomNavigationView?
BottomNavigationView не показывает заголовок меню, которые неактивны.
Как показать названия всех элементов меню в bottomNavigationBar? Проблема в том, что в моем случае показан только заголовок элемента, который нажат.
13 ответов:
реализация
BottomNavigationView
имеет условие: когда больше чем 3 деталя после этого используют режим переноса.на данный момент Вы не можете изменить его через существующий API, и единственный способ отключить режим сдвига-использовать отражение.
вам понадобится вспомогательный класс:
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), код выше использует отражение и не будет работать, если proguard запутать
Так как библиотека поддержки 28.0.0-alpha1:
<android.support.design.widget.BottomNavigationView app:labelVisibilityMode="labeled" />
чтобы отключить текстовую анимацию, вы также можете использовать ее в своих измерениях.xml-файл:
<dimen name="design_bottom_navigation_active_text_size">12sp</dimen>
ответ Пшемыслава в Котлине как функция расширения
@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) } }
использование (с расширениями Kotlin Android):
bottom_navigation_view.disableShiftMode()
теперь вы можете использовать приложение: labelVisibilityMode="[помечено, не помечено, выбрано, авто] " в 28-alpha
labeled сохранит все метки видимыми.
без метки будут отображаться только значки.
выбранный будет отображаться только метка для выбранного элемента и элементов сдвига.
авто будет выбирать помеченные или выбранные на основе количества элементов, которые у вас есть. с надписью на 1-3 пунктов и 3 пунктов.
чтобы отключить анимацию текста и уменьшить размер шрифта, используйте это в ваших dimens.xml-файл:
<dimen name="design_bottom_navigation_text_size">10sp</dimen> <dimen name="design_bottom_navigation_active_text_size">10sp</dimen>
у меня было какое-то странное поведение с BottomNavigationView. Когда я выбирал какой-либо элемент/фрагмент в нем, фрагмент толкает BottomNavigationView немного ниже, поэтому текст BottomNavigationView идет ниже экрана, поэтому видны только значки, а текст скрывается при нажатии любого элемента.
Если вы столкнулись с этим странным поведением, то здесь решение. Просто удалите
android:fitsSystemWindows="true"
в корневом макете фрагмента. Просто снимите это и бум! BottomNavigationView будет работать нормально, теперь он может быть показан с текстом и значком. У меня это было в моем корневом координаторе фрагмента.
также не забудьте добавить
BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
в вашей деятельности, чтобы отключить режим сдвига. Хотя это не совсем связано с заданным вопросом, но все же я нахожу это полезным.
это сторонняя библиотека, которую я использую, и у нее есть много вариантов настройки, таких как отключение режима сдвига, отображение только значков, установка размера значков и т. д. BottomNavigationViewEx
как указывали другие, так как библиотека поддержки 28.0.0-alpha1 можно:
<android.support.design.widget.BottomNavigationView app:labelVisibilityMode="labeled" />
или вы можете настроить его программно.
Примечание: Если вы обновляете более старую версию библиотеки поддержки, не забудьте поднять версию compile SDK. Проверьте версии поддержки libraray здесь: поддержка версий библиотеки
однако, вы все равно можете получить labelVisibilityMode нет нашел сообщение при компиляции, если ваше приложение зависит от более старых версий библиотеки поддержки проектирования. Если это так, попробуйте обновить до версии данной зависимости, которая зависит по крайней мере от версии 28.0.0-alpha1 библиотеки поддержки проектирования. Если это невозможно, определите зависимость явно.
Если вы используете Gradle
- вы можете проверить ваши depdendecies мимо работает зависимости задача и поиск номер версии com.андроид.поддержка:дизайн.
чтобы добавить зависимость поддержки дизайна явно в вашем построить.gradle:
реализация ' com.андроид.поддержка:дизайн:28.0.0'
для обновленного ответа используется значение по умолчанию. Обновление до последней библиотеке
реализация " com.андроид.поддержка:дизайн:28.0.0"
и положить в BottomNavigationView XML атрибуты
app:itemHorizontalTranslationEnabled="false"
вы можете поставить его также как программно
bottomNavigationView.setItemHorizontalTranslationEnabled(false);
Вы можете найти источник здесь BottomNavigationView
надеюсь, что это поможет вам.
чтобы полностью удалить анимацию:
если вы также хотите избавиться от этой раздражающей маленькой анимации верхнего поля, вам нужно больше кода отражения. Вот полное решение, которое удаляет любую анимацию:
@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; }