BottomNavigationView не показывает название меню, которое неактивно.
Как показать заголовки всех элементов меню в bottomNavigationBar? Проблема в том, что в моем случае отображается только название элемента, который нажат.
BottomNavigationView не показывает название меню, которое неактивно.
Как показать заголовки всех элементов меню в bottomNavigationBar? Проблема в том, что в моем случае отображается только название элемента, который нажат.
Реализация 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 mShiftingMode
поле mShiftingMode
.
-keepclassmembers class android.support.design.internal.BottomNavigationMenuView {
boolean mShiftingMode;
}
Спасибо Мухаммеду Альфаифи за указание на эту проблему и предоставление фрагмента.
ОБНОВЛЕНИЕ 2
Как отметила Jolanda Verhoef, новая библиотека поддержки (28.0.0-alpha1
), а также новая библиотека компонентов материалов (1.0.0-beta01
) предлагает открытое свойство, которое можно использовать для управления режимом смещения над 3 пунктами меню.
<com.google.android.material.bottomnavigation.BottomNavigationView
...
app:labelVisibilityMode="labeled"
...
/>
В библиотеке компонентов материалов это также применимо, если есть 5 пунктов меню.
ОБНОВЛЕНИЕ 3
Как также указал @ThomasSunderland, вы можете установить для этого свойства значение false app:itemHorizontalTranslation="false"
без Enabled
постфикса, чтобы отключить смещение анимации.
Вы можете ознакомиться с полным руководством по стилю BottomNavigation здесь.
Поскольку библиотека поддержки 28.0.0-alpha1:
<android.support.design.widget.BottomNavigationView
app:labelVisibilityMode="labeled" />
Чтобы отключить текстовую анимацию, вы также можете использовать это в вашем файле измерения .xml:
<dimen name="design_bottom_navigation_active_text_size">12sp</dimen>
Вам также может понадобиться добавить это в свой манифест:
tools:override="true"
Теперь вы можете использовать app:labelVisibilityMode="[labeled, unlabeled, selected, auto]"
в 28-alpha
labeled
будут отображаться на всех ярлыках.unlabeled
покажет только значки.selected
будет отображать только ярлык для выбранного элемента и сдвинуть элементы.auto
выберет маркировку или выбранную в зависимости от количества элементов, которые у вас есть. помечены для 1-3 элементов и выбраны для элементов 3+.Пшемысский ответ в Котлине как функция расширения
@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()
Чтобы отключить текстовую анимацию и уменьшить размер шрифта, используйте это в файле dimens.xml:
<dimen name="design_bottom_navigation_text_size">10sp</dimen>
<dimen name="design_bottom_navigation_active_text_size">10sp</dimen>
Работает для меня
bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
или же
<android.support.design.widget.BottomNavigationView
app:labelVisibilityMode="labeled" />
ОБНОВИТЬ
в Android sdk версии 28 и выше они изменили item.setShiftingMode(false)
на item.setShifting(false)
Также они удалили поле mShiftingMode
Таким образом, использование будет
BottomNavigationHelper.removeShiftMode(bottomNav);
bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
private static final class BottomNavigationHelper {
@SuppressLint("RestrictedApi")
static void removeShiftMode(BottomNavigationView view) {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
for (int i = 0; i < menuView.getChildCount(); i++) {
BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
//noinspection RestrictedApi
item.setShifting(false);
item.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
// set once again checked value, so view will be updated
//noinspection RestrictedApi
item.setChecked(item.getItemData().isChecked());
}
}
}
Как уже отмечали другие, начиная с библиотеки поддержки 28.0.0-alpha1 возможно:
<android.support.design.widget.BottomNavigationView
app:labelVisibilityMode="labeled" />
или вы можете установить его программно.
Примечание: если вы обновляете старую версию библиотеки поддержки, не забудьте поднять версию SDK для компиляции. Проверьте версии библиотеки поддержки здесь: Поддержка библиотеки версий
Однако при компиляции вы все равно можете получить сообщение labelVisibilityMode not found, если ваше приложение зависит от более старых версий библиотеки поддержки проектирования. Если это так, попробуйте обновить до версии с данной зависимостью, которая зависит по крайней мере от версии 28.0.0-alpha1 библиотеки поддержки проектирования. Если это невозможно, определите зависимость явно.
Если вы используете Gradle
Чтобы явно добавить поддержку поддержки дизайна в ваш build.gradle:
реализация 'com.android.support:design:28.0.0'
Для получения обновленного ответа используйте значение по умолчанию. Обновление до последней библиотеки дизайна
реализация "com.android.support:design:28.0.0"
и поместите в свои атрибуты xml BottomNavigationView xml
app:itemHorizontalTranslationEnabled="false"
вы можете использовать его также как программно
bottomNavigationView.setItemHorizontalTranslationEnabled(false);
Вы можете найти источник здесь BottomNavigationView
Надеюсь, это поможет вам.
У меня было какое-то странное поведение с BottomNavigationView. Когда я выбирал в нем какой-либо элемент/фрагмент, фрагмент подталкивает BottomNavigationView немного ниже, поэтому текст BottomNavigationView идет ниже экрана, поэтому отображаются только значки и текст скрывается при нажатии любого элемента.
Если вы столкнулись с этим странным поведением, то вот решение. Просто удалите
android:fitsSystemWindows="true"
в корневой компоновке фрагмента. Просто удалите это и бум! BottomNavigationView будет работать нормально, теперь его можно показать с текстом и значком. У меня было это в моем корневом координаторе. Выделить фрагмент.
Также не забудьте добавить
BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
в вашей активности, чтобы отключить режим переключения. Хотя это не совсем связано с заданным вопросом, но все же я считаю это полезным.
Это сторонняя библиотека, которую я использую, и она имеет множество параметров настройки, таких как отключение режима сдвига, отображение только значков, установка размера значков и т.д. BottomNavigationViewEx
Если вы также хотите избавиться от этой раздражающей анимации с малым максимальным показателем, вам нужно больше кода отражения. Здесь полное решение, которое удаляет любую анимацию:
@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;
}
В BottomNavigationView
добавьте app:labelVisibilityMode="unlabeled"
<android.support.design.widget.BottomNavigationView
app:menu="@menu/bn_menu"
android:layout_height="56dp"
android:layout_width="match_parent"
app:labelVisibilityMode="unlabeled">
</android.support.design.widget.BottomNavigationView>
что приводит к следующему
обновите свою библиотеку поддержки до 28.0.0.
bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
Если вы используете support: design: 28.0.0 добавьте эту строку app: labelVisibilityMode = "unlabeled" в ваш BottomNavigationView
просто хочу добавить, что выше этого метода disableShiftMode добавить ниже код тоже. @SuppressLint ( "RestrictedApi")
Попробуйте это макет
app:labelVisibilityMode="labeled"
или на уровне кода mNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
И обновите вашу библиотеку поддержки дизайна до 28.0. +
Это очень просто, просто добавьте свойство в BottomNaviationView
app:labelVisibilityMode="unlabeled"
Вы можете использовать это для отображения текста и значков в BottomNevigationView от 3 до 5 элементов и остановки сдвига.
app:labelVisibilityMode="labeled"
Но вы столкнетесь с проблемой обрезки длинного текста в BottmNevigationView для 5 элементов. для этого я нашел хорошее решение для остановки смещения текста, а также иконки BottomNevigationView. Вы также можете остановить смещение текста и значков в BottomNevigationView. Фрагменты кода приведены здесь.
1. Добавьте эту строку кода в BottomNevigationView, как показано
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="@dimen/seventy_dp"
android:layout_semitransparent="true"
android:background="@color/colorBottomNev"
android:showAsAction="always|withText"
app:itemIconTint="@drawable/bottom_navigation_colors"
app:itemTextColor="@drawable/bottom_navigation_colors"
app:itemTextAppearanceActive="@style/BottomNavigationViewTextStyle"
app:itemTextAppearanceInactive="@style/BottomNavigationViewTextStyle"
app:menu="@menu/bottom_navigation_menu"
app:labelVisibilityMode="labeled"/>
2. Добавьте пункты меню следующим образом: -
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_catalogue"
android:icon="@drawable/catalogue"
android:title="@string/catalogue"
android:enabled="true"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_contracts"
android:icon="@drawable/contract"
android:title="@string/contracts"
android:enabled="true"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_prospects"
android:icon="@drawable/prospect"
android:title="@string/prospects"
android:enabled="true"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_performance"
android:icon="@drawable/performance"
android:title="@string/performance"
android:enabled="true"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_advance"
android:icon="@drawable/advance"
android:title="@string/advance"
android:enabled="true"
app:showAsAction="ifRoom" />
</menu>
3. Добавьте этот стиль в файл style.xml:
<style name="BottomNavigationViewTextStyle">
<item name="android:fontFamily">@font/montmedium</item>
<item name="android:textSize">10sp</item>
<item name="android:duplicateParentState">true</item>
<item name="android:ellipsize">end</item>
<item name="android:maxLines">1</item>
</style>
4) Добавьте их в папку Dimen
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<dimen name="design_bottom_navigation_text_size" tools:override="true">10sp</dimen>
<dimen name="design_bottom_navigation_active_text_size" tools:override="true">10sp</dimen>
</resources>
Я получил помощь по этой ссылке и ссылке. Вы также можете получить помощь, изучив эти ссылки. Это мне очень помогает. Надеюсь, это также поможет вам. Спасибо....