BottomNavigationView всегда отображает значки и текстовые метки

Я использую android.support.design.widget.BottomNavigationView из библиотеки поддержки дизайна версии 25

compile 'com.android.support:design:25.0.0'

<android.support.design.widget.BottomNavigationView
        android:id="@+id/bottomBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="center"
        app:itemBackground="@color/colorPrimary"
        app:menu="@menu/bottom_navigation_main"
        android:forceHasOverlappingRendering="true"/>

Когда в @ menu / bottom_navigation_main есть только три действия, он всегда отображает и значки, и текстовые метки.

Каким образом можно отображать одновременно и значки, и текстовые метки при наличии более трех действий.


person Ammad Ali    schedule 03.11.2016    source источник
comment
В меню bottom_navigation_main.xml, если у вас есть android: showAsAction = ifRoom, измените его на android: showAsAction = always для каждого элемента.   -  person Shashank Udupa    schedule 03.11.2016
comment
Нет, не сработало. я пробовал это раньше.   -  person Ammad Ali    schedule 03.11.2016
comment
Можете ли вы показать свой XML-файл меню   -  person Shashank Udupa    schedule 03.11.2016
comment
'‹? Xml version = 1.0 encoding = utf-8?› ‹Menu xmlns: android = схем. android.com/apk/res/android xmlns: app = schemas.android.com / apk / res-auto ›‹ item android: id = @ + id / action_favorites app: showAsAction = always / ›‹ item android: id = @ + id / action_schedules app: showAsAction = always / ›‹ item android : id = @ + id / action_music app: showAsAction = always / ›‹ item android: id = @ + id / account android: enabled = true app: showAsAction = always / ›‹/menu› '   -  person Ammad Ali    schedule 03.11.2016
comment
Возможный дубликат Как отключить режим сдвига BottomNavigationView?   -  person Przemysław Piechota. kibao    schedule 26.12.2016
comment
поместите приложение: labelVisibilityMode = с меткой в ​​BottomNavigationView.   -  person Shrawan    schedule 24.08.2018
comment
labelVisibilityMode помог мне! Большое спасибо!   -  person Marty Miller    schedule 01.10.2018
comment
Очень полезный вопрос. Спасибо   -  person Yi Xiang Chong    schedule 22.04.2021


Ответы (10)


Для тех, кто все еще ищет решение и не хочет полагаться на сторонние библиотеки или отражение во время выполнения, BottomNavigationView в библиотеке поддержки 28 / Jetpack изначально поддерживает всегда наличие текстовой метки.

Это метод, который вы ищете .

Или в XML app:labelVisibilityMode="labeled"

person shaishgandhi    schedule 26.05.2018
comment
какая версия библиотеки мне нужна? - person DaniloDeQueiroz; 29.05.2018
comment
библиотека поддержки 28-alpha1 + - person shaishgandhi; 29.05.2018
comment
Вы также можете изменить режим видимости на автоматический, чтобы отображать текст значка только при нажатии / фокусировке. Код: app: labelVisibilityMode = auto - person Kenny Dabiri; 26.11.2019
comment
Ты мужчина! Спасибо, это работает с последней версией библиотеки материалов. - person sud007; 20.02.2020
comment
Потрясающие. Спасибо - person Titus Sutio Fanpula; 16.04.2021
comment
Это очень полезно. Спасибо - person Yi Xiang Chong; 22.04.2021
comment
Также работает с библиотекой androix - person Ebenmelu Noah; 23.05.2021

ОБНОВЛЕНИЕ ОТ 8 мая 2018 г.

Вы можете использовать app:labelVisibilityMode="labeled" прямо в <android.support.design.widget.BottomNavigationView />

Источник: https://developer.android.com/reference/com/google/android/material/bottomnavigation/LabelVisibilityMode

Не нужно это подробное решение ниже.

ПРЕДЫДУЩИЙ ОТВЕТ

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

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

android:fitsSystemWindows="true"

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

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

BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);

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

Вот этот класс:

public class BottomNavigationViewHelper {

    @SuppressLint("RestrictedApi")
    public static void removeShiftMode(BottomNavigationView view) {
        //this will remove shift mode for bottom navigation 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);
                // set once again checked value, so view will be updated
                item.setChecked(item.getItemData().isChecked());
            }

        } catch (NoSuchFieldException e) {
            Log.e("ERROR NO SUCH FIELD", "Unable to get shift mode field");
        } catch (IllegalAccessException e) {
            Log.e("ERROR ILLEGAL ALG", "Unable to change value of shift mode");
        }
    }
}
person Kishan Solanki    schedule 21.11.2017
comment
Это в сочетании с ответом STAR_ZERO решило мою проблему! - person Christopher Smit; 19.02.2018
comment
В звонке у вас disableShiftMode, а в классе removeShiftMode. Помимо этого небольшого несоответствия, ваш ответ решил проблему для меня. Теперь у меня есть пять пунктов меню без сдвига и с текстом + значок. Большое спасибо, большое! - person Yamakuzure; 03.04.2018
comment
Идеально. Когда у вас более 3 элементов в нижней части навигации, появляется режим переключения. Используя это, вы можете отключить это смещение, и, следовательно, все значки с текстом отображаются одновременно. - person Kishor Bikram Oli; 25.04.2018
comment
Это неограниченный API, и он не работает в библиотеке поддержки версии 28. +. Принятый ответ @shaishgandhi - более правильный способ сделать это. - person okarakose; 25.09.2018

В версии 25 это сложно.

Попробуйте этот код. Но я считаю, что это не очень хорошее решение.

BottomNavigationView navigationView = (BottomNavigationView) findViewById(R.id.bottomBar);
BottomNavigationMenuView menuView = (BottomNavigationMenuView) navigationView.getChildAt(0);
for (int i = 0; i < menuView.getChildCount(); i++) {
    BottomNavigationItemView itemView = (BottomNavigationItemView) menuView.getChildAt(i);
    itemView.setShiftingMode(false);
    itemView.setChecked(false);
}
person STAR_ZERO    schedule 05.11.2016
comment
В Android Studio следует добавить такой код: `` // noinspection RestrictedApi itemView.setShiftingMode (false); // без проверки RestrictedApi itemView.setChecked (false); `` '' - person Jiezhi.G; 26.04.2017
comment
это все еще перемещает предметы - person CodeToLife; 31.05.2017
comment
Идеально !! отображает как значок, так и текст. Но режим переключения (false) не работает. - person Minkoo; 30.08.2017
comment
Это в сочетании с ответом KishanSolanki124 решило мою проблему! - person Christopher Smit; 19.02.2018

Вот функция расширения Kotlin, которая сочетает в себе решение @STAR_ZERO и @ KishanSolanki124.

fun BottomNavigationView.disableShiftMode() {
    val menuView = getChildAt(0) as BottomNavigationMenuView

    menuView.javaClass.getDeclaredField("mShiftingMode").apply {
        isAccessible = true
        setBoolean(menuView, false)
        isAccessible = false
    }

    @SuppressLint("RestrictedApi")
    for (i in 0 until menuView.childCount) {
        (menuView.getChildAt(i) as BottomNavigationItemView).apply {
            setShiftingMode(false)
            setChecked(false)
        }
    }
}

Чтобы использовать это:

myBottomNavigation.disableShiftMode()
person chetbox    schedule 17.05.2018

Вы хотите этого эффекта?

Щелкните здесь, чтобы просмотреть изображение

Если это так, я рекомендую вам попробовать BottomNavigationViewEx

person ittianyu    schedule 13.11.2016
comment
Ваша библиотека - хорошая и впечатляющая работа. Но я стремился достичь этой функциональности с помощью библиотеки дизайна 25.0.0. К сожалению, это противоречит практике разработки Android. - person Ammad Ali; 13.11.2016
comment
Это противоречит спецификациям Material Design. Если вы прочитаете предоставленный вами документ, вы увидите, что в нем явно указано, что если есть четыре или пять действий, отображать неактивные представления только в виде значков. - person Felipe; 31.07.2017

Вы можете использовать это для отображения текста и значков в BottomNevigationView.

app:labelVisibilityMode="labeled"

Если вы используете это, вы сможете просматривать как значок, так и текст.

<android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/bottom_navigation_view"
    android:layout_alignParentBottom="true"
    app:menu="@menu/bottom_navigation_menu"/>
person Kumar Ajay A.K    schedule 11.04.2019

Вы можете использовать app: labelVisibilityMode = "labeled" непосредственно в

<com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:labelVisibilityMode="labeled"
        android:elevation="8dp"
        android:layout_alignParentBottom="true"
        app:itemBackground="@drawable/bottom_navi"
        app:itemTextColor="@color/white"
        app:itemIconTint="@color/white"
        app:menu="@menu/bottom_nav_menu_managment" />
person kishan verma    schedule 03.03.2020

в классе BottomNavigationView есть поле BottomNavigationMenuView, а в BottomNavigationMenuView есть поле BottomNavigationItemView [], которое представляет собой элементы на нижней панели.

Скажем, n - количество элементов, BottomNavigationMenuView вызовет BottomNavigationItemView.setShiftingMode (n> 3) для каждого члена массива BottomNavigationItemView []. Эта функция определяет поведение (показывать заголовок всегда или только при выборе).

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

    BottomNavigationView bottomNavigationView= (BottomNavigationView) findViewById(R.id.bottom_navigation);


//  get the private BottomNavigationMenuView field 
        Field f = null;
        try {
            f = bottomNavigationView.getClass().getDeclaredField("mMenuView");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        f.setAccessible(true);
        BottomNavigationMenuView menuView=null;
        try {
             menuView = (BottomNavigationMenuView) f.get(bottomNavigationView); 
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

//  get the private BottomNavigationItemView[]  field 
        try {
            f=menuView.getClass().getDeclaredField("mButtons");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        f.setAccessible(true);
        BottomNavigationItemView[] mButtons=null;
        try {
            mButtons = (BottomNavigationItemView[]) f.get(menuView); 
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }


        for(int i=0;i<mButtons.length;i++){
            mButtons[i].setShiftingMode(false);
            mButtons[i].setChecked(true);
        }
person wei wang    schedule 04.11.2016
comment
Это очень хорошо, просто нам нужно убедиться, что BottomNavigationMenuView также не смещается. - ›f = menuView.getClass (). GetDeclaredField (mShiftingMode); f.setAccessible (правда); f.setBoolean (menuView, ложь); - person stephane k.; 22.01.2017

Чтобы показать заголовки полностью. Попробуйте этот код Kotlin:

@SuppressLint("RestrictedApi")
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_ofree)

    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)

    val menuView = navigation.getChildAt(0) as BottomNavigationMenuView
    for (i in 0 until menuView.childCount) {
        val itemView = menuView.getChildAt(i) as BottomNavigationItemView
        itemView.setShiftingMode(false)
        itemView.setChecked(false)
    }
}
person Harry Zhang    schedule 15.01.2018

Альтернатива BottomNavigationViewEx: BottomBar

person Mateusz Budzisz    schedule 10.11.2017