BottomNavigationView mostra sempre sia le icone che le etichette di testo


125

Sto usando android.support.design.widget.BottomNavigationView dalla versione 25 della libreria di supporto alla progettazione

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"/>

Quando sono presenti solo tre azioni in @ menu / bottom_navigation_main, vengono sempre visualizzate sia le icone che le etichette di testo.

Qual è il modo per visualizzare sempre sia le icone che le etichette di testo quando ci sono più di tre azioni.


Nel tuo menu bottom_navigation_main.xml, se hai android: showAsAction = "ifRoom" cambialo in android: showAsAction = "sempre" per ogni elemento.
— Shashank Udupa

No, non ha funzionato. l'avevo provato prima.
— Sviluppatore Android

Puoi mostrare il tuo file xml del menu
— Shashank Udupa

"<? xml version =" 1.0 "encoding =" utf-8 "?> <menu xmlns: android =" schemas.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> "
— Sviluppatore Android

4
place app: labelVisibilityMode = "labeled" in BottomNavigationView.
— Shrawan

Risposte:


327

Per chiunque sia ancora alla ricerca di una soluzione e non voglia fare affidamento su librerie di terze parti o riflessione di runtime, BottomNavigationView in Support Library 28 / Jetpack supporta nativamente la presenza di un'etichetta di testo.

Questo è il metodo che stai cercando.

O in XML, app:labelVisibilityMode="labeled"


quale versione della libreria mi serve?
— DaniloDeQueiroz

libreria di supporto 28-
— alpha1

Puoi anche cambiare la modalità di visibilità in "auto" per mostrare il testo dell'icona solo quando viene premuto / focalizzato. Codice: app: labelVisibilityMode = "auto"
— Kenny Dabiri

Tu sei l'uomo! Grazie, funziona con l'ultima versione di Material Library.
— sud007

68

AGGIORNAMENTO DALL'8 maggio 2018

Puoi usare app:labelVisibilityMode="labeled" direttamente in<android.support.design.widget.BottomNavigationView />

Fonte: https://developer.android.com/reference/com/google/android/material/bottomnavigation/LabelVisibilityMode

Non hai bisogno di questa soluzione lunga sotto.

RISPOSTA PRECEDENTE

Ho avuto un comportamento strano con BottomNavigationView. Quando stavo selezionando un elemento / frammento in esso, il frammento spinge BottomNavigationView un po 'più in basso, quindi il testo di BottomNavigationView va sotto lo schermo, quindi solo le icone erano visibili e il testo viene nascosto quando si fa clic su qualsiasi elemento.

Se stai affrontando questo strano comportamento, ecco la soluzione. Basta rimuovere

android:fitsSystemWindows="true"

nel layout radice del frammento. Basta rimuovere questo e boom! BottomNavigationView funzionerà bene, ora può essere mostrato con testo e icona. Avevo questo nella mia radice CoordinatorLayout del frammento.

Inoltre, non dimenticare di aggiungere

BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);

nella tua attività per disabilitare la modalità cambio.

Ecco quella classe:

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

Questo in combinazione con la risposta di STAR_ZERO ha risolto il mio problema!
— Christopher Smit

Nella chiamata che hai disableShiftModee in classe removeShiftMode. A parte questa piccola discrepanza, la tua risposta ha risolto il problema per me. Ora ho cinque voci di menu senza spostamento e con testo + icona. Grazie molto molto!
— Yamakuzure

Perfetto. Quando sono presenti più di 3 elementi nella navigazione inferiore di, viene visualizzata una modalità di spostamento. Usando questo, puoi disabilitare lo spostamento e quindi tutte le icone con il testo appaiono contemporaneamente.
— Kishor Bikram Oli

1
Questa è un'API senza restrizioni e non funziona con la libreria di supporto versione 28. +. La risposta accettata da @shaishgandhi è un modo più corretto per farlo.
— okarakose

19

È difficile nella versione 25.

Prova questo codice. Ma penso che non sia una buona soluzione.

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

In Android Studio, aggiungere un codice come questo: `` // noinspection RestrictedApi itemView.setShiftingMode (false); // noinspection RestrictedApi itemView.setChecked (false); ``
— Jiezhi

4
è ancora sposta gli articoli
— CodeToLife

1
Perfetto !! visualizza sia l'icona che il testo. Ma la modalità di cambio (falso) non funziona.
— Minkoo

Questo in combinazione con la risposta di KishanSolanki124 ha risolto il mio problema!
— Christopher Smit

11

Ecco una funzione di estensione di Kotlin che combina la soluzione @STAR_ZERO e @ 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)
        }
    }
}

Per usarlo:

myBottomNavigation.disableShiftMode()

10

Vuoi questo effetto?

Clicca qui per visualizzare l'immagine

In tal caso, ti ho consigliato di provare BottomNavigationViewEx。


1
La tua libreria è un lavoro buono e impressionante Ma stavo cercando di ottenere questa funzionalità utilizzando la libreria di progettazione 25.0.0 Sfortunatamente è contro la pratica di progettazione di
— Android

Ciò non è contro le specifiche di Material Design, secondo la "Barra di navigazione inferiore fissa" nei documenti . Inoltre, i miei ringraziamenti personali per aver condiviso questa fantastica libreria.
— Serg de Adelantado

1
Questo è contro le specifiche di Material Design. Se leggi il documento che hai fornito, vedrai che dice esplicitamente "Se ci sono quattro o cinque azioni, mostra le viste inattive solo come icone".
— Felipe

8

Puoi usarlo per mostrare sia il testo che le icone su BottomNevigationView

app:labelVisibilityMode="labeled"

Se lo stai utilizzando, sarai in grado di visualizzare sia l'icona che il testo

<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"/>

6

Puoi utilizzare app: labelVisibilityMode = "labeled" direttamente in

<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" />

5

nella classe BottomNavigationView c'è un campo BottomNavigationMenuView e in BottomNavigationMenuView c'è un campo BottomNavigationItemView [], che sono gli elementi nella barra inferiore.

Diciamo che n è il numero di elementi, BottomNavigationMenuView chiamerà BottomNavigationItemView.setShiftingMode (n> 3) su ogni membro della matrice BottomNavigationItemView []. Questa funzione decide il comportamento (mostra il titolo sempre o solo al momento della selezione).

quindi il modo per mostrare sempre i titoli è provare a chiamare questo metodo e puoi usare la reflection per accedere ai campi privati.

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

Questo è molto buono, dobbiamo solo assicurarci che BottomNavigationMenuView non si sposti. -> f = menuView.getClass (). getDeclaredField ("mShiftingMode"); f.setAccessible (true); f.setBoolean (menuView, false);
— stephane k.

4

Per mostrare i titoli fino in fondo. Prova questo codice 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)
    }
}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.