BottomNavigationView z więcej niż 3 pozycjami: tytuł karty jest ukryty


85

Używam BottomNavigationView przy użyciu biblioteki projektowania Android Support Desing 25. Ale kiedy przełączam karty, tytuł drugiej karty jest ukrywany. Ale nie ma problemu z ukrywaniem faktycznego widoku nawigacji u dołu. Ale mój się chowa.

MyBottomNavigation

Ale chcę, żeby tak wyglądało. Masz jakiś pomysł, żeby to zrobić? czego mi brakuje?

ActualBottomNavigation

Oto mój kod:

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>

próbowałeś app:showAsAction="alwayszamiastifRoom
Yassine BELDI

Próbowałem, ale wciąż się ukrywa
Yunus Haznedar


1
@YunusHaznedar, jeśli pozycja jest większa niż 3, tekst zawsze będzie ukryty ...
Shashank Verma

1
Hej, @DanXPrado dzięki za udostępnienie rozwiązania. Oznaczyłem twoją odpowiedź jako zaakceptowaną. Miłego kodowania.
Yunus Haznedar

Odpowiedzi:


139

Rozwiązanie wykorzystujące odbicie już nie działa, ponieważ pole mShiftingMode zostało usunięte.

Teraz jest na to łatwy sposób: użyj biblioteki obsługi 28 i po prostu dodaj app:labelVisibilityMode="labeled"do swojej BottomNavigationViewdeklaracji XML.

Mam nadzieję, że to pomoże.


Pracujesz jak mistrz, ale jak sprawić, by był przewijany kołowo?
Shailendra Madda

@ShylendraMadda Proponuję opublikować to jako nowe pytanie, ponieważ nie jest związane z tym pytaniem.
Danilo Prado,

1
Jak to nie jest domyślne zachowanie ... Zmarnowałem kilka godzin z app: showAsAction, android: visible, android: enabled i kilkoma innymi hackami. Dzięki!
Danish Khan,

94

AKTUALIZACJA

removeShiftMode () nie jest już potrzebna, ponieważ w bibliotece wsparcia 28.0.0-alpha1 możemy teraz dodawać etykiety .

W XML:

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

W przypadku zmiany programowej:

mBottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED); 

Aby to zadziałało: zaktualizuj bibliotekę obsługi projektowania do wersji 28.0.0-alpha1

Oto dobra lektura

DLA STARSZEJ BIBLIOTEKI WSPARCIA:

w swoim bottom_bar_menu.xml.Zmień showAsActionatrybut

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

w build.gradle:

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

NAWIGACJA DOLNA ZOBACZ WIĘCEJ NIŻ 3 ELEMENTY: użyj removeShiftMode()metody

w BottomNavigationViewHelper.javaużyciu:

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);
            }
        }
    }

Zadzwoń za pomocą:

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

Spowoduje to wyłączenie animacji przesunięcia tekstu tytułu i umożliwi wyświetlanie tekstu.


2
Nie, nadal się ukrywa. Próbowałem „zawsze” i „zawsze | z tekstem”
Yunus Haznedar

1
jeden z tytułów twojego przedmiotu jest duży, czy widok innego jest zablokowany? spróbuj z małym tytułem i rysunkami ..
rafsanahmad007

1
zobacz tę linię w tutotrial, który obserwujeszIt’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
świetna odpowiedź, dzięki
Hamza Abdullah

2
Rozwiązanie odbicia działa całkiem dobrze com.android.support:design:25.4.0, ale nie działa com.android.support:design:26.1.0, więc wycofuję trochę docelowy zestaw SDK i wersję zależności.
Evi Song

10

Po zeskanowaniu kodu źródłowego BottomNavigationView znalazłem

mShiftingMode = mMenu.size() > 3;

w linii 265 BottomNavigationMenuView.java oznacza to, że gdy rozmiar menu jest większy niż 3, tytuł zakładki będzie ukryty. Więc jeśli chcesz wyświetlić tytuł karty, wystarczy pobrać kod z kompilacji i zmienić go na poniżej.

mShiftingMode = mMenu.size() > 5;

PS: Maksymalna liczba kart w BottonNavigationView musi wynosić od 3 do 5. Kod można pobrać na stronie BottomNavigationViewNew wprowadź opis obrazu tutaj


Mam własny CustomBottomView, który rozszerza BottomNavigationView, czy istnieje sposób na ustawienie tej właściwości zamiast tego?
JPM

1
Nie widzę wiersza „BottomNavigationMenuView”, który dotyczy limitu trzech kart. Może kod się zmienił?
programista Androida

8

Utwórz klasę 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);
        }
    }
}   

Połączenie

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

1
Ma SuppressLint, który rozwiązuje problem annoacji restrykcyjnych API
code4j

3

Funkcja rozszerzenia 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")
    }
}

Dziękuję Panu. Bardzo doceniony.
Yunus Haznedar

1
item.setShiftingMode(false)jest terazitem.setShifting(false)
Sim

2

Prawie użyłem odpowiedzi rafsanahmad007, ale przetłumaczę ją na Kotlin. Podzielę się nim dla przyszłych wędrowców

@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
To rozwiązanie nie jest już ważne, zaakceptowane rozwiązanie jest poprawne przez @DanXPrado
jpardogo

Dzięki za poinformowanie mnie
Karma Maker

0

To działa dla mnie w API 26:

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


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

Utwórz tę metodę w swoim działaniu lub fragmencie, w którym chcesz wywołać:

 @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

Możesz użyć tego do wyświetlania tekstu i ikon w widoku BottomNevigationView dla 3 do 5 elementów i zatrzymania przesuwania.

 app:labelVisibilityMode="labeled"

Ale napotkasz problem z wycinaniem długiego tekstu w BottmNevigationView dla 5 elementów. w tym celu znalazłem dobre rozwiązania, aby zatrzymać przesuwanie tekstu, a także ikony BottomNevigationView. Możesz także zatrzymać przesuwanie tekstu, a także ikon w widoku BottomNevigationView. Tutaj zamieszczono fragmenty kodu.

1. Dodaj tę linię kodu w BottomNevigationView, jak pokazano

<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. Dodaj elementy menu w następujący sposób: -

 <?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. Dodaj ten styl w pliku 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) Dodaj je w folderze 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>

Mam pomocy od tych linku i odwołuje Ty możesz również uzyskać uzyskać pomoc studiując te links.This pomaga mnie lot.Hope to również pomóc. Dzięki....


0

szybko naprawiono po prostu dodaj aplikację: labelVisibilityMode = "oznaczone" w 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" />

Uwaga

  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

Należy zwrócić uwagę, mimo że nie ma to zastosowania w tym przypadku.

Ten wzorzec może być użyty, jeśli masz od 3 do 5 miejsc docelowych najwyższego poziomu, do których chcesz nawigować.

Aby włączyć wyświetlanie tytułu ikony, wykonaj następujące czynności:

  1. Upewnij się, że XML elementu menu (bottom_navigation_menu) ma następującą strukturę: -

    <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. Dodaj następujący kod do aplikacji kodu 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"/>

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.