BottomNavigationView з більш ніж 3 елементами: заголовок вкладки приховується


85

Я використовую BottomNavigationView з використанням бібліотеки Desing для підтримки Android 25. Але коли я перемикаю вкладки, заголовок іншої вкладки приховується. Але немає жодної проблеми, що стосується фактичного нижнього перегляду навігації. Але моя ховається.

MyBottomNavigation

Але я хочу, щоб це так виглядало. Будь-яка ідея зробити це? Чого мені не вистачає?

ActualBottomNavigation

Ось мій код:

Activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.yunus.ototakip.MainActivity">

<FrameLayout
    android:id="@+id/main_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/bottom_navigation"
    android:layout_alignParentTop="true">
</FrameLayout>

<android.support.design.widget.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    app:itemBackground="@color/colorPrimary"
    app:itemIconTint="@color/beyaz"
    app:itemTextColor="@color/beyaz"
    app:menu="@menu/bottombar_menu" />

bottom_bar_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
 <item
android:id="@+id/bb_menu_arac"
android:enabled="true"
android:icon="@drawable/icon_car"
android:title="@string/araclarim"
app:showAsAction="ifRoom" />
 <item
android:id="@+id/bb_menu_yakin"
android:enabled="true"
android:icon="@drawable/icon_yer"
android:title="@string/yakinimdakiler"
app:showAsAction="ifRoom" />
  <item
android:id="@+id/bb_menu_yaklasan"
android:enabled="true"
android:icon="@drawable/icon_takvim"
android:title="@string/yaklasanlar"
app:showAsAction="ifRoom" />

<item
    android:id="@+id/bb_menu_ipucu"
    android:enabled="true"
    android:icon="@drawable/icon_ipucu"
    android:title="@string/ipuclari"
    app:showAsAction="ifRoom" />
 </menu>

ви пробували app:showAsAction="alwaysзамість цьогоifRoom
Ясін БЕЛДІ

Я спробував, але це все ще приховує
Юнус Хазнедар


1
@YunusHaznedar, якщо елемента більше 3, тоді текст завжди буде приховувати ...
Shashank Verma

1
Привіт, @DanXPrado дякуємо за поділ рішенням. Я позначив вашу відповідь як прийняту. Щасливого кодування.
Юнус Газнедар

Відповіді:


139

Рішення з використанням відбиття вже не працює, оскільки поле mShiftingMode було видалено.

Зараз це простий спосіб: скористайтеся бібліотекою підтримки 28 і просто додайте app:labelVisibilityMode="labeled"до своєї BottomNavigationViewдекларації XML.

Сподіваюся, це допоможе.


Працюючи як чемпіон, але як зробити його круговим прокручуванням?
Шайлендра Мадда

@ShylendraMadda Пропоную опублікувати це як нове запитання, оскільки воно не пов’язане з цим питанням.
Данило Прадо,

1
Як це не поведінка за замовчуванням ... Я витратив кілька годин на app: showAsAction, android: visible, android: enabled та купу інших хаків. Дякую!
датський хан

94

ОНОВЛЕННЯ

removeShiftMode () більше не потрібен, оскільки в бібліотеці підтримки 28.0.0-alpha1 тепер ми можемо додавати Мітки .

У XML:

<android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled" />

Для програмних змін:

mBottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED); 

Щоб це працювало: оновіть бібліотеку підтримки дизайну до 28.0.0-alpha1

Ось гарне читання

ДЛЯ СТАРШОЇ БІБЛІОТЕКИ ПІДТРИМКИ:

у вашому bottom_bar_menu.xml.Змініть showAsActionатрибут

<item android:id="@id/menu_item"
android:title="text"
android:icon="@drawable/drawable_resource_name"
android:showAsAction="always|withText" />

у build.gradle:

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

ВНИЗ НАВІГАЦІЯ ПЕРЕГЛЯНУТИ БІЛЬШЕ, ніж 3 ПУНКТИ: використовуйте removeShiftMode()метод

у BottomNavigationViewHelper.javaвикористанні:

import android.annotation.SuppressLint;
import android.support.design.internal.BottomNavigationItemView;
import android.support.design.internal.BottomNavigationMenuView;
import android.support.design.widget.BottomNavigationView;
import java.lang.reflect.Field;

    public class BottomNavigationViewHelper {
        @SuppressLint("RestrictedApi")
        public static void removeShiftMode(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("BottomNav", "Unable to get shift mode field", e);
            } catch (IllegalAccessException e) {
                Log.e("BottomNav", "Unable to change value of shift mode", e);
            }
        }
    }

Зателефонуйте за допомогою:

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

Це вимкне анімацію зсуву тексту заголовка та дозволить відображати текст.


2
Ні, це все ще ховається. Я пробував "завжди" і "завжди | withText"
Юнус Газнедар

1
заголовок одного елемента ур великий, що спричиняє блокування подання іншого? спробуйте з невеликим заголовком та зображеннями, які можна
малювати

1
див. цей рядок у навчальному матеріалі, за яким ви стежитеIt’s important to note that the maximum number of items we can display is 5. This may change at any point, so it’s important to check this by using the getMaxItem() method provided by the BottomNavigationView class rather than hard-coding the value yourself.
rafsanahmad007

1
чудова відповідь, Дякую
Хамза Абдулла

2
Рішення для відображення працює досить добре com.android.support:design:25.4.0, але не працює com.android.support:design:26.1.0, тому я трохи відкочую цільовий SDK та версію залежностей.
Evi Song

10

Після сканування вихідний код BottomNavigationView я знаходжу

mShiftingMode = mMenu.size() > 3;

у рядку 265 BottomNavigationMenuView.java , це означає, що якщо розмір меню більше 3, заголовок вкладки буде приховано. Отже, якщо ви хочете показати заголовок вкладки, вам просто потрібно отримати код зі збірки та змінити на нижче.

mShiftingMode = mMenu.size() > 5;

PS: Максимальна кількість вкладок BottonNavigationView повинна становити від 3 до 5. Ви можете отримати код на BottomNavigationViewNew введіть тут опис зображення


У мене є власний CustomBottomView, який розширює BottomNavigationView, чи є спосіб встановити це властивість замість цього?
JPM

1
Я не бачу рядка "BottomNavigationMenuView", що становить приблизно 3 межі вкладок. Можливо, код змінився?
розробник android

8

Створіть клас BottomNavigationViewHelper

import android.annotation.SuppressLint;
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 {
    @SuppressLint("RestrictedApi")
    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);
if(menuView.getChildCount()<6)
           {
            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);
        }
    }
}   

Телефонуйте

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

1
Він має SuppressLint, який вирішує проблему
анотацій restrictAPI

3

Функція розширення Kotlin:

@SuppressLint("RestrictedApi")
fun BottomNavigationView.removeShiftMode(){
    val menuView = this.getChildAt(0) as BottomNavigationMenuView
    try {
        val shiftingMode = menuView.javaClass.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) {
        e.printStackTrace()
        Timber.tag("BottomNav").e( e, "Unable to get shift mode field")
    } catch (e: IllegalAccessException) {
        Timber.tag("BottomNav").e( e, "Unable to change value of shift mode")
    }
}

Спасибі пане. Дуже вдячний.
Yunus Haznedar

1
item.setShiftingMode(false)заразitem.setShifting(false)
Сім

2

Я в значній мірі використовував відповідь rafsanahmad007, але переклав її на Котлін. Дозвольте поділитися ним для майбутніх мандрівників

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

1
Це рішення вже не дійсне, прийняте рішення правильне @DanXPrado
jpardogo

Thx за те, що повідомив мене
Karma Maker

0

Це працює для мене в API 26:

 navigation = (BottomNavigationView) view.findViewById(R.id.bottom_navigation);


     try{disableShiftMode(navigation);}catch(Exception ew){}

Внесіть цей метод у свою активність або фрагмент, куди ви хочете зателефонувати:

 @SuppressLint("RestrictedApi")
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);
            item.setShiftingMode(false);

            item.setChecked(item.getItemData().isChecked());
        }
    } catch (NoSuchFieldException e) {

    } catch (IllegalAccessException e) {

    }
}

0

Ви можете використовувати це для показу як тексту, так і піктограм на 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>

Я отримав допомогу від цих посилання і посилання .Ви також можете отримати отримати допомогу, вивчаючи ці links.This мені допомагає lot.Hope це також допоможе вам. Дякую....


0

швидко виправити, просто додайте додаток: labelVisibilityMode = "позначено" у xml

<android.support.design.widget.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    app:itemBackground="@color/colorPrimary"
    app:itemIconTint="@drawable/bottom_navigation_color_selector"
    app:itemTextColor="@drawable/bottom_navigation_color_selector"
    app:labelVisibilityMode="labeled"
    app:menu="@menu/menu_bottom_navigation" />

Примітка

  implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'

0

Зауважимо одне, хоча це не стосується цього випадку.

Цей шаблон можна використовувати, коли у вас є від 3 до 5 пунктів призначення верхнього рівня для навігації.

Щоб увімкнути відображення заголовка піктограми, виконайте такі дії:

  1. Переконайтесь, що елемент меню XML (bottom_navigation_menu) структурований таким чином: -

    <item
        android:id="@+id/action_home"
        android:enabled="true"
        android:icon="@drawable/ic_action_home"
        android:title="HOME"
        app:showAsAction="ifRoom"/>
    
    <item
        android:id="@+id/action_favourites"
        android:enabled="true"
        android:icon="@drawable/ic_action_favourite"
        android:title="FAVOURITES"
        app:showAsAction="ifRoom"/>
    
    <item
        android:id="@+id/action_basket"
        android:enabled="true"
        android:icon="@drawable/ic_action_basket"
        android:title="BASKET"
        app:showAsAction="ifRoom"/>
    

  2. Додайте в програму коду BottomNavigationView наступне : labelVisibilityMode = "labeled"

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:background="@android:color/white"
    app:itemIconTint="@android:color/black"
    app:itemTextColor="@android:color/black"
    app:menu="@menu/bottom_navigation_menu"
    app:labelVisibilityMode="labeled"/>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.