Wie deaktiviere ich den BottomNavigationView-Shift-Modus?

146

BottomNavigationView zeigt keine inaktiven Menütitel an.

Wie werden Titel aller Menüelemente in der bottomNavigationBar angezeigt? Das Problem ist, dass in meinem Fall nur der Titel des angeklickten Elements angezeigt wird.

Geben Sie hier die Bildbeschreibung ein

Natan Rubinstein
quelle
1
Mögliches Duplikat der neuen unteren Navigationsleiste
Radhey
Hier ist eine nützliche Antwort, wenn Sie eine Animation vollständig entfernen möchten : stackoverflow.com/a/51052247/2352699
Fred Porciúncula

Antworten:

330

Implementierung von BottomNavigationViewhas Bedingung: Wenn mehr als 3 Elemente vorhanden sind, verwenden Sie den Shift-Modus.

Derzeit können Sie es nicht über die vorhandene API ändern. Die einzige Möglichkeit, den Shift-Modus zu deaktivieren, besteht in der Verwendung von Reflection.

Sie benötigen eine Hilfsklasse:

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

Wenden Sie dann die disableShiftModeMethode auf Ihren BottomNavigationViewCode an. Denken Sie jedoch daran, dass Sie die Menüansicht nach dem Aufblasen ausführen müssen, wenn Sie sie in Ihrem Code aufblasen.

Anwendungsbeispiel:

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

PS.

Denken Sie daran, dass Sie diese Methode jedes Mal ausführen müssen, wenn Sie Menüelemente in Ihrem Menü ändern BottomNavigationView.

AKTUALISIEREN

Sie müssen auch die Proguard-Konfigurationsdatei (z. B. proguard-rules.pro) aktualisieren. Der obige Code verwendet Reflection und funktioniert nicht, wenn Proguard das mShiftingModeFeld verschleiert .

-keepclassmembers class android.support.design.internal.BottomNavigationMenuView { 
    boolean mShiftingMode; 
}

Vielen Dank an Muhammad Alfaifi, der auf dieses Problem hingewiesen und einen Ausschnitt bereitgestellt hat .

UPDATE 2

Wie Jolanda Verhoef betonte, bietet die neue Support-Bibliothek ( 28.0.0-alpha1) und auch die neue Material Components-Bibliothek ( 1.0.0-beta01) eine öffentliche Eigenschaft, mit der der Verschiebemodus über 3 Menüelemente bearbeitet werden kann.

<com.google.android.material.bottomnavigation.BottomNavigationView
    ...
    app:labelVisibilityMode="labeled"
    ... 
/>

In der Materialkomponentenbibliothek gilt dies auch, wenn 5 Menüpunkte vorhanden sind.

UPDATE 3

Wie auch @ThomasSunderland hervorhob, können Sie diese Eigenschaft app:itemHorizontalTranslation="false"ohne EnabledPostfix auf false setzen , um die Verschiebungsanimation zu deaktivieren.

Die vollständige Anleitung zum Stylen der BottomNavigation finden Sie hier

Przemysław Piechota. Kibao
quelle
10
**** Proguard :(
Muhammad Alfaifi
17
Das Feld wird verschleiert, so dass es nicht möglich ist, seinen Wert zu ändern, es sei denn, Sie schließen es in Ihrer Proguard-Rules-Datei aus
Muhammad Alfaifi
8
-keepclassmembers class android.support.design.internal.BottomNavigationMenuView {boolean mShiftingMode; }
Muhammad Alfaifi
8
Manchmal frage ich mich wirklich, warum Google Entwicklern die Implementierung von Ansichten aufzwingt. Während es in der Google+ App selbst 4 Optionen gibt, sollte diese einfache Funktion über eine einfache Funktion zugänglich sein, falls verfügbar! Ein ähnliches Problem gab es beim TabLayout, das viel später in der Support-Bibliothek behoben wurde. Vielen Dank für diese Problemumgehung an Original Replier und @MuhammadAlfaifi für die Verbesserung.
Sud007
19
Die neue Support-Bibliothek (28.0.0-alpha1) unterstützt das Ändern dieses Verhaltens über die App: labelVisibilityMode = "label"
Jolanda Verhoef
50

Seit der Unterstützungsbibliothek 28.0.0-alpha1:

<android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled" />
Junbin Deng
quelle
1
Ich verwende diese Support-Bibliotheksversion, erhalte aber immer noch den Fehler "labelVisibilityMode" nicht gefunden.
Sagar Maiyad
1
Funktioniert richtig. Keine Notwendigkeit zum Nachdenken. Vielen Dank
Bhupesh
1
@ Riser stellen Sie sicher, dass Sie app:nicht verwendenandroid:
Carson Holzheimer
28

Um die Textanimation zu deaktivieren, können Sie dies auch in Ihrer Datei dimensions.xml verwenden:

<dimen name="design_bottom_navigation_active_text_size">12sp</dimen>

Möglicherweise müssen Sie dies auch in Ihr Manifest aufnehmen:

tools:override="true"
Pafoid
quelle
funktioniert nicht. Ich glaube, ich musste dies nur in /values/dimens.xml hinzufügen?
Rohan Kandwal
10
@ RohanKandwal müssen hinzufügentools:override="true"
Boy
@ Boy Danke, werde es versuchen.
Rohan Kandwal
Ändern Sie nur die Textgröße.
Der Typ
Ich muss nur so in meine dimension.xml-Datei einfügen:<dimen name="design_bottom_navigation_active_text_size" tools:ignore="PrivateResource">12sp</dimen>
Fernando Barbosa
22

Sie können jetzt app:labelVisibilityMode="[labeled, unlabeled, selected, auto]"in verwenden28-alpha

  • labeled hält alle Beschriftungen sichtbar.
  • unlabeled zeigt nur Symbole an.
  • selected zeigt nur die Beschriftung für das ausgewählte Element und die Verschiebungselemente an.
  • autowählt beschriftet oder ausgewählt basierend auf der Anzahl der Elemente, die Sie haben. beschriftet für 1-3 Artikel und ausgewählt für 3+ Artikel.
Aidan Laing
quelle
1
danke Lunkie! Dies ist die beste und einfachste Lösung für mich
Gregriggins36
Wo kann diese Codezeile hinzugefügt werden? Ich habe versucht hinzuzufügen, aber es wurde ein Fehler nicht gefunden.
Abdulwahid
@Abdulwahid Sie können dies in der XML der unteren Navigationsleiste hinzufügen, sobald Sie Support-Bibliothek 28 oder höher haben
Aidan Laing
@Lunkie danke jetzt ist es klar einmal Support-Bibliothek 28
Abdulwahid
17

Przemysławs Antwort in Kotlin als Erweiterungsfunktion

@SuppressLint("RestrictedApi")
fun BottomNavigationView.disableShiftMode() {
    val menuView = getChildAt(0) as BottomNavigationMenuView
    try {
        val shiftingMode = menuView::class.java.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) {
        Log.e(TAG, "Unable to get shift mode field", e)
    } catch (e: IllegalStateException) {
        Log.e(TAG, "Unable to change value of shift mode", e)
    }
}

Verwendung (mit Kotlin Android Extensions):

bottom_navigation_view.disableShiftMode()
ElegyD
quelle
Arbeiten für Kotlin. Warum müssen wir diese Annotation verwenden? @SuppressLint ("RestrictedApi") können Sie bitte erklären?
Ranjith Kumar
11

Funktioniert bei mir

bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

oder

<android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled" />
UgAr0FF
quelle
meins funktionierte einwandfrei bis Ziel = 27, aber von Ziel = 28 ist es kaputt, Text wird nicht mehr angezeigt. Aber setLabelVisibilityMode macht den Trick für mich, funktioniert jetzt wie ein Zauber
Witz4me
10

Um die Textanimation zu deaktivieren und die Schriftgröße zu verringern, verwenden Sie Folgendes in Ihrer Datei dimensions.xml:

<dimen name="design_bottom_navigation_text_size">10sp</dimen> 
<dimen name="design_bottom_navigation_active_text_size">10sp</dimen>
Abhishek
quelle
Man kann Navigate-> File...> design_bottom_navigation_item.xmlsehen , dass es keinen anderen Weg.
Arekolek
6

AKTUALISIEREN

in Android SDK - Version 28 und höher sie haben sich geändert item.setShiftingMode(false)zuitem.setShifting(false)

Auch sie haben das Feld entfernt mShiftingMode

So wird die Nutzung sein

 BottomNavigationHelper.removeShiftMode(bottomNav);
 bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);


 private static final class BottomNavigationHelper {
    @SuppressLint("RestrictedApi")
    static void removeShiftMode(BottomNavigationView view) {
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
        for (int i = 0; i < menuView.getChildCount(); i++) {
            BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
            //noinspection RestrictedApi
            item.setShifting(false);
            item.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

            // set once again checked value, so view will be updated
            //noinspection RestrictedApi
            item.setChecked(item.getItemData().isChecked());
        }
    }
}
Narek Hayrapetyan
quelle
Sie können diesen Code unten verwenden. @SuppressLint ( "RestrictedApi") Spaß removeShiftMode (Ansicht: BottomNavigationView) {val Menü - Am = view.getChildAt (0) als BottomNavigationMenuView menuView.labelVisibilityMode = LabelVisibilityMode.LABEL_VISIBILITY_LABELED menuView.buildMenuView ()}
Tief P
5

Wie andere bereits betont haben, ist es seit der Unterstützung der Bibliothek 28.0.0-alpha1 möglich:

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

oder Sie können es programmgesteuert einstellen .

Hinweis: Wenn Sie ein Upgrade von einer älteren Version der Support-Bibliothek durchführen, vergessen Sie nicht, die SDK-Kompilierungsversion zu aktivieren. Überprüfen Sie die Versionen der Support-Bibliothek hier: Versionen der Support-Bibliothek

Möglicherweise wird beim Kompilieren jedoch weiterhin die Meldung labelVisibilityMode nicht gefunden angezeigt , wenn Ihre App von älteren Versionen der Designunterstützungsbibliothek abhängt. Wenn dies der Fall ist, versuchen Sie, ein Upgrade auf eine Version der angegebenen Abhängigkeit durchzuführen, die mindestens von der Version 28.0.0-alpha1 der Designunterstützungsbibliothek abhängt. Wenn dies nicht möglich ist, definieren Sie die Abhängigkeit explizit.

Wenn Sie Gradle verwenden

  1. Sie können Ihre Abhängigkeiten überprüfen, indem Sie die Aufgabe " Abhängigkeiten" ausführen und nach der Versionsnummer von com.android.support:design suchen .
  2. So fügen Sie in Ihrem build.gradle explizit Abhängigkeiten zur Designunterstützung hinzu :

    Implementierung 'com.android.support:design:28.0.0'

Richárd Bogdán
quelle
4

Für aktualisierte Antwort mit der Standardeinstellung. Update auf die neueste Designbibliothek

Implementierung "com.android.support:design:28.0.0"

und in Ihre BottomNavigationView-XML-Attribute einfügen

app:itemHorizontalTranslationEnabled="false"

Sie können es auch programmatisch ausdrücken

bottomNavigationView.setItemHorizontalTranslationEnabled(false);

Die Quelle finden Sie hier BottomNavigationView

Hoffe das hilft dir.

Lester L.
quelle
Was unterscheidet das von app:labelVisibilityMode?
Wonsuc
@wonsuc Hier geht es um die Animation von Symbol und Text, die das ausgewählte Element animiert. Während labelVisibilityMode zum Anzeigen anzeigt, ob Sie ein Symbol mit Text anzeigen möchten oder nur ein Symbol, das bei Auswahl angezeigt werden soll.
Lester L.
3

Zu Ihrem BottomNavigationViewhinzufügenapp:labelVisibilityMode="unlabeled"

<android.support.design.widget.BottomNavigationView
        app:menu="@menu/bn_menu"
        android:layout_height="56dp"
        android:layout_width="match_parent"
        app:labelVisibilityMode="unlabeled">

</android.support.design.widget.BottomNavigationView>

was zu folgendem führt

Android Bottom Navigation View Text und Umschalt deaktivieren

Alles ist gut
quelle
3

Es ist sehr einfach. Fügen Sie einfach eine Eigenschaft in BottomNaviationView hinzu

app:labelVisibilityMode="unlabeled"
Nevil Ghelani
quelle
2

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.disableShiftMode(bottomNavigationView);

in Ihrer Aktivität, um den Schaltmodus zu deaktivieren. Es hängt zwar nicht genau mit der gestellten Frage zusammen, aber ich finde das trotzdem hilfreich.

Kishan Solanki
quelle
1
@ abbath0767 haben Sie gesehen Link dieses? Könnte für Sie hilfreich sein.
Kishan Solanki
Ich dachte, ich hätte schon alles versucht, vielen Dank, ich hatte nicht erwartet, die Antwort, nach der ich suchte, direkt zu finden.
BekaBot
1
Pleasure @BekaBot
Kishan Solanki
2

Dies ist eine Bibliothek von Drittanbietern, die ich verwende. Sie verfügt über viele Anpassungsoptionen wie das Deaktivieren des Schichtmodus, das Anzeigen nur von Symbolen , das Festlegen der Symbolgröße usw. BottomNavigationViewEx

Pei
quelle
2

So entfernen Sie Animationen vollständig:

Wenn Sie auch diese nervige kleine Animation am oberen Rand loswerden möchten, benötigen Sie mehr Reflexionscode. Hier ist die Komplettlösung, mit der Animationen entfernt werden:

@SuppressLint("RestrictedApi")
private 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);

            Field shiftAmount = item.getClass().getDeclaredField("mShiftAmount");
            shiftAmount.setAccessible(true);
            shiftAmount.setInt(item, 0);
            shiftAmount.setAccessible(false);

            item.setChecked(item.getItemData().isChecked());
        }
    } catch (NoSuchFieldException e) {
        Timber.e(e, "Unable to get fields");
    } catch (IllegalAccessException e) {
        Timber.e(e, "Unable to change values");
    }
}

Und stellen Sie sicher, dass Sie dies zu Ihrer Proguard-Konfigurationsdatei hinzufügen:

-keepclassmembers class android.support.design.internal.BottomNavigationMenuView { 
    boolean mShiftingMode; 
}
-keepclassmembers class android.support.design.internal.BottomNavigationItemView { 
    int mShiftAmount;
}
Fred Porciúncula
quelle
Android 9 (API-Level 28) führt neue Einschränkungen für die Verwendung von Nicht-SDK-Schnittstellen ein. Dies würde nicht funktionieren, wenn auf 28 ausgerichtet wird. Developer.android.com/about/versions/pie/…
ernestkamara
2

Aktualisieren Sie Ihre Support-Bibliothek auf 28.0.0.

bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
M Moersalin
quelle
1

Wenn Sie support: design: 28.0.0 verwenden, fügen Sie diese Zeilen-App hinzu: labelVisibilityMode = "unlabeled" zu Ihrer BottomNavigationView

Omar Hassan
quelle
0

Ich möchte nur hinzufügen, dass über dieser Methode disableShiftMode auch unter Code hinzugefügt wird. @ SuppressLint ("RestrictedApi")

Aleesha Kanwal
quelle
-1

Sie können dies verwenden, um sowohl Text als auch Symbole in BottomNevigationView für 3 bis 5 Elemente anzuzeigen und die Verschiebung zu beenden.

 app:labelVisibilityMode="labeled"

In BottmNevigationView für 5 Elemente treten jedoch Probleme beim Schneiden von Langtext auf. Dafür habe ich gute Lösungen gefunden, um das Verschieben von Text zu stoppen, sowie Symbole von BottomNevigationView. Sie können auch das Verschieben von Text und Symbolen in BottomNevigationView beenden. Hier finden Sie Snipshots des Codes.

1. Fügen Sie diese Codezeile wie gezeigt in BottomNevigationView hinzu

<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. Fügen Sie Menüelemente wie folgt hinzu: -

 <?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. Fügen Sie diesen Stil in die Datei style.xml ein:

 <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) Fügen Sie diese in den Ordner Dimen ein

<?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>

Ich habe Hilfe von diesem Link bekommen und Link erhalten. Sie können auch Hilfe erhalten, indem Sie diese Links studieren. Dies hilft mir sehr. Ich hoffe, dies hilft Ihnen auch. Vielen Dank....

Rahul Kushwaha
quelle