BottomNavigationView con più di 3 elementi: il titolo della scheda è nascosto


85

Sto usando BottomNavigationView con l'utilizzo di Android Support Desing Library 25. Ma quando cambio le schede, il titolo dell'altra scheda si nasconde. Ma non ci sono problemi di occultamento nella visualizzazione di navigazione dal basso. Ma il mio si nasconde.

MyBottomNavigation

Ma voglio che sia così. Qualche idea per farlo? Cosa mi manca?

ActualBottomNavigation

Ecco il mio codice:

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>

hai provato app:showAsAction="alwaysinvece diifRoom
Yassine BELDI

Ho provato, ma si nasconde ancora
Yunus Haznedar il


1
@YunusHaznedar se l'articolo è superiore a 3 testo, quindi sarà sempre nascondere ...
Shashank Verma

1
Ehi, @DanXPrado grazie per aver condiviso la soluzione. Ho contrassegnato la tua risposta come accettata. Buona codifica.
Yunus Haznedar

Risposte:


143

La soluzione che utilizza la riflessione non funziona più perché il campo mShiftingMode è stato rimosso.

C'è un modo semplice per farlo ora: usa Support Library 28 o superiore e aggiungi semplicemente app:labelVisibilityMode="labeled"alla tua BottomNavigationViewdichiarazione XML.

Spero che sia d'aiuto.


Funzionando come un campione, ma come renderlo scorrevole scorrevole?
Shailendra Madda

@ShylendraMadda ti suggerisco di postarla come una nuova domanda poiché non è correlata a questa domanda.
Danilo Prado

1
In che modo questo non è il comportamento predefinito ... Ho sprecato qualche ora con app: showAsAction, android: visible, android: enabled e un sacco di altri hack. Grazie!
Danese Khan

94

AGGIORNARE

removeShiftMode () non è più necessario, poiché nella libreria di supporto 28.0.0-alpha1 ora possiamo aggiungere etichette .

In XML:

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

Per la modifica a livello di codice:

mBottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED); 

Affinché funzioni: aggiorna la libreria di supporto alla progettazione a 28.0.0-alpha1

Ecco una buona lettura

PER BIBLIOTECA DI SUPPORTO PIÙ VECCHIA:

nel tuo bottom_bar_menu.xml.Cambia l' showAsActionattributo

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

in build.gradle:

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

NAVIGAZIONE INFERIORE VISUALIZZA PIÙ DI 3 ELEMENTI: removeShiftMode()metodo di utilizzo

in BottomNavigationViewHelper.javauso:

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

Chiamalo usando:

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

Disabiliterà l'animazione dello spostamento del testo del titolo e abiliterà la visualizzazione del testo.


2
No, si sta ancora nascondendo. Ho provato "sempre" e "sempre | con testo"
Yunus Haznedar

1
uno dei titoli degli articoli è grande sta causando il blocco della vista di altri? prova con un titolo piccolo e immagini disegnabili ..
rafsanahmad007

1
vedi questa riga sul tutotrial che stai seguendoIt’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
ottima risposta, grazie
Hamza Abdullah

2
La soluzione di riflessione funziona abbastanza bene com.android.support:design:25.4.0, ma non riesce com.android.support:design:26.1.0, quindi ripristino leggermente l'SDK di destinazione e la versione delle dipendenze.
Evi Song

10

Dopo la scansione del codice sorgente di BottomNavigationView trovo

mShiftingMode = mMenu.size() > 3;

nella riga 265 di BottomNavigationMenuView.java , significa che mentre la dimensione del menu è maggiore di 3, il titolo della scheda sarà nascosto. Quindi, se vuoi mostrare il titolo della scheda, devi solo ottenere il codice dalla build e passare al seguente.

mShiftingMode = mMenu.size() > 5;

PS: il numero massimo di schede BottonNavigationView deve essere compreso tra 3 e 5. È possibile ottenere il codice su BottomNavigationViewNew inserisci qui la descrizione dell'immagine


Ho il mio CustomBottomView che estende BottomNavigationView, c'è un modo per impostare quella proprietà invece?
JPM

1
Non vedo la riga di "BottomNavigationMenuView" che riguarda il limite di 3 schede. Forse il codice è cambiato?
sviluppatore Android

8

Crea una classe 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);
        }
    }
}   

Chiamata

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

1
Ha SuppressLint che risolve il problema di annuncio di limitazione dell'API
code4j

3

Funzione di estensione 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")
    }
}

Grazie Signore. Molto apprezzato.
Yunus Haznedar

1
item.setShiftingMode(false)è adessoitem.setShifting(false)
Sim

2

Ho praticamente usato la risposta rafsanahmad007 ma la traduco in Kotlin. Lasciatemelo condividere per i futuri vagabondi

@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
Questa soluzione non è più valida, la soluzione accettata è corretta da @DanXPrado
jpardogo

Grazie per avermelo fatto sapere
Karma Maker

1

Una cosa da notare anche se non si applica in questo caso.

Questo modello può essere utilizzato quando si hanno da 3 a 5 destinazioni di primo livello verso cui navigare.

Per abilitare la visualizzazione del titolo dell'icona, procedi come segue:

  1. Assicurati che il tuo elemento XML del menu (bottom_navigation_menu) sia strutturato come segue: -

    <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. Aggiungi quanto segue all'app del codice 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"/>


0

Questo funziona per me nell'API 26:

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


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

Imposta questo metodo nella tua attività o frammento dove vuoi chiamare:

 @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

Puoi usarlo per mostrare sia il testo che le icone su BottomNevigationView da 3 a 5 elementi e interrompere lo spostamento.

 app:labelVisibilityMode="labeled"

Ma dovrai affrontare un problema di taglio di testo lungo su BottmNevigationView per 5 elementi. per questo, ho trovato una buona soluzione per interrompere lo spostamento del testo e delle icone di BottomNevigationView. Puoi anche interrompere lo spostamento del testo e delle icone anche su BottomNevigationView. Qui vengono forniti degli snapshot del codice.

1. Aggiungere questa riga di codice in BottomNevigationView come mostrato

<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. Aggiungi voci di menu come segue: -

 <?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.Aggiungi questo stile nel file 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) Aggiungili nella cartella 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>

Ho ricevuto aiuto da questi link e link . Puoi anche ottenere aiuto studiando questi link . Questo mi aiuta molto. Spero che anche questo ti aiuti. Grazie....


0

risolto rapidamente basta aggiungere app: labelVisibilityMode = "labeled" in 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" />

Nota

  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'
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.