BottomNavigationView zeigt jederzeit sowohl Symbole als auch Textbeschriftungen an

124

Ich verwende android.support.design.widget.BottomNavigationView aus der Design Support Library Version 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"/>

Wenn in @ menu / bottom_navigation_main nur drei Aktionen vorhanden sind, werden jederzeit sowohl Symbole als auch Textbeschriftungen angezeigt.

Wie können jederzeit Symbole und Textbeschriftungen angezeigt werden, wenn mehr als drei Aktionen ausgeführt werden?

Android-Entwickler
quelle
Wenn Sie in Ihrem Menü bottom_navigation_main.xml android: showAsAction = "ifRoom" haben, ändern Sie es für jedes Element in android: showAsAction = "always".
Shashank Udupa
Nein, es hat nicht funktioniert. Ich hatte es schon einmal versucht.
Android Developer
Können Sie Ihre Menü-XML-Datei zeigen
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 =" immer "/> <item android: id =" @ + id / action_schedules "app: showAsAction =" immer "/> < item android: id = "@ + id / action_music" app: showAsAction = "immer" /> <item android: id = "@ + id / account" android: enabled = "true" app: showAsAction = "immer" /> </ menu> '
Android Developer
4
Platziere die App: labelVisibilityMode = "beschriftet" in BottomNavigationView.
Shrawan

Antworten:

324

Für alle, die noch nach einer Lösung suchen und sich nicht auf Bibliotheken von Drittanbietern oder Laufzeitreflexionen verlassen möchten, unterstützt BottomNavigationView in Support Library 28 / Jetpack von Haus aus immer die Verwendung von Textbezeichnungen.

Dies ist die Methode, nach der Sie suchen.

Oder in XML, app:labelVisibilityMode="labeled"

Shaishgandhi
quelle
Welche Bibliotheksversion brauche ich?
DaniloDeQueiroz
Unterstützungsbibliothek 28-alpha1 +
shaishgandhi
Sie können den Sichtbarkeitsmodus auch auf "Auto" ändern, um Symboltext nur beim Drücken / Fokussieren anzuzeigen. Code: app: labelVisibilityMode = "auto"
Kenny Dabiri
Du bist der Mann! Vielen Dank, dass dies mit der neuesten Version der Materialbibliothek funktioniert.
sud007
68

UPDATE AB 8. Mai 2018

Sie können app:labelVisibilityMode="labeled" direkt in verwenden<android.support.design.widget.BottomNavigationView />

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

Benötigen Sie diese unten lange Lösung nicht.

VORHERIGE ANTWORT

Ich hatte ein seltsames Verhalten mit BottomNavigationView. Wenn ich ein Element / Fragment darin ausgewählt habe, drückt das Fragment BottomNavigationView etwas nach unten, sodass der Text von BottomNavigationView unter dem Bildschirm angezeigt wird, sodass nur Symbole sichtbar sind und der Text beim Klicken auf ein Element ausgeblendet wird.

Wenn Sie mit diesem seltsamen Verhalten konfrontiert sind, dann ist hier die Lösung. Einfach entfernen

android:fitsSystemWindows="true"

in Ihrem Root-Layout des Fragments. Einfach entfernen und boomen! BottomNavigationView funktioniert einwandfrei, jetzt kann es mit Text und Symbol angezeigt werden. Ich hatte dies in meinem Root CoordinatorLayout des Fragments.

Vergessen Sie auch nicht hinzuzufügen

BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);

in Ihrer Aktivität, um den Schaltmodus zu deaktivieren.

Hier ist diese Klasse:

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");
        }
    }
}
Kishan Solanki
quelle
Dies in Kombination mit der Antwort von STAR_ZERO löste mein Problem!
Christopher Smit
In dem Anruf, den Sie haben disableShiftMode, und in der Klasse removeShiftMode. Abgesehen von dieser kleinen Diskrepanz löste Ihre Antwort das Problem für mich. Ich habe jetzt fünf Menüs ohne Verschiebung und mit Text + Symbol. Vielen Dank sehr viel!
Yamakuzure
Perfekt. Wenn Ihre untere Navigation mehr als 3 Elemente enthält, wird ein Verschiebungsmodus angezeigt. Auf diese Weise können Sie diese Verschiebung deaktivieren und daher werden alle Symbole mit Text gleichzeitig angezeigt.
Kishor Bikram Oli
1
Dies ist eine uneingeschränkte API und funktioniert nicht mit der Support-Bibliothek Version 28. +. Akzeptierte @ shishishandhi-Antwort ist der richtige Weg, dies zu tun.
Okarakose
19

In Version 25 ist es schwierig.

Versuchen Sie diesen Code. Aber ich denke, es ist keine gute Lösung.

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);
}
STAR_ZERO
quelle
Fügen Sie in Android Studio folgenden Code hinzu: `` `// noinspection RestrictedApi itemView.setShiftingMode (false); // noinspection RestrictedApi itemView.setChecked (false); `` `
Jiezhi.G
4
Es werden immer noch Artikel
verschoben
1
Perfekt !! Zeigt sowohl Symbol als auch Text an. Aber der Schaltmodus (falsch) funktioniert nicht.
Minkoo
Dies in Kombination mit der Antwort von KishanSolanki124 löste mein Problem!
Christopher Smit
11

Hier ist eine Kotlin-Erweiterungsfunktion, die die Lösung von @STAR_ZERO und @ KishanSolanki124 kombiniert.

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

Um es zu benutzen:

myBottomNavigation.disableShiftMode()
Chetbox
quelle
10

Wollen Sie dies erreichen?

Klicken Sie hier, um das Bild anzuzeigen

Wenn ja, empfahl ich Ihnen zu versuchen BottomNavigationViewEx .

ittianyu
quelle
1
Ihre Bibliothek ist eine gute und beeindruckende Arbeit. Aber ich wollte diese Funktionalität mit der Designbibliothek 25.0.0 erreichen. Leider ist dies gegen die Android-Designpraxis
Android Developer
Dies widerspricht nicht den Materialdesign-Spezifikationen gemäß der "festen unteren Navigationsleiste" in den Dokumenten . Mein persönlicher Dank auch für das Teilen dieser großartigen Bibliothek.
Serg de Adelantado
1
Dies widerspricht den Material Design-Spezifikationen. Wenn Sie das von Ihnen bereitgestellte Dokument lesen, wird explizit angezeigt, dass "Wenn vier oder fünf Aktionen vorhanden sind, werden inaktive Ansichten nur als Symbole angezeigt".
Felipe
8

Sie können dies verwenden, um sowohl Text als auch Symbole in BottomNevigationView anzuzeigen

app:labelVisibilityMode="labeled"

Wenn Sie dies verwenden, können Sie sowohl das Symbol als auch den Text anzeigen

<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"/>
Kumar Ajay AK
quelle
6

Sie können die App: labelVisibilityMode = "label" direkt in verwenden

<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" />
Kishan Verma
quelle
5

In der BottomNavigationView-Klasse gibt es ein BottomNavigationMenuView-Feld und in BottomNavigationMenuView ein BottomNavigationItemView [] -Feld. Dies sind die Elemente in der unteren Leiste.

Angenommen, n ist die Anzahl der Elemente. BottomNavigationMenuView ruft BottomNavigationItemView.setShiftingMode (n> 3) für jedes Mitglied des BottomNavigationItemView [] -Arrays auf. Diese Funktion entscheidet über das Verhalten (Titel immer oder nur bei Auswahl anzeigen).

Um die Titel immer anzuzeigen, müssen Sie versuchen, diese Methode aufzurufen, und Sie können Reflection verwenden, um auf die privaten Felder zuzugreifen.

    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);
        }
Wei Wang
quelle
Das ist sehr gut, nur müssen wir sicherstellen, dass sich auch BottomNavigationMenuView nicht verschiebt. -> f = menuView.getClass (). getDeclaredField ("mShiftingMode"); f.setAccessible (true); f.setBoolean (menuView, false);
stephane k.
4

Um die Titel vollständig anzuzeigen. Versuchen Sie diesen Kotlin-Code:

@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)
    }
}
Harry Zhang
quelle
1

Alternative zu BottomNavigationViewEx : BottomBar

Mateusz Budzisz
quelle