it-roy-ru.com

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 есть только три действия, он всегда отображает значки и текстовые метки.

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

42
Android Developer

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

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

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

98
shaishgandhi

ОБНОВЛЕНИЕ С 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");
        }
    }
}
47
KishanSolanki124

Это сложно в версии 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);
}
18
STAR_ZERO

Вот функция расширения 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()
10
chetbox

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

Click here to view the image

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

9
ittianyu

в классе 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);
        }
5
wei wang

Чтобы показать названия полностью. Попробуйте этот код 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)
    }
}
4
Harry Zhang

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

1
Mateusz Budzisz

Вы можете использовать это для отображения текста и значков в 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"/>
0
Kumar Ajay A.K

попробуй это, у меня сработало

app:labelVisibilityMode="labeled"
0
saigopi