Comment désactiver le mode de décalage BottomNavigationView?

146

BottomNavigationView n'affiche pas le titre du menu qui est inactif.

Comment afficher les titres de tous les éléments de menu dans bottomNavigationBar? Le problème est que dans mon cas, il ne montre que le titre de l'élément sur lequel l'utilisateur clique.

entrez la description de l'image ici

Natan Rubinstein
la source
1
Copie possible de la nouvelle barre de navigation inférieure Android
Radhey
Voici une réponse utile si vous souhaitez supprimer complètement une animation: stackoverflow.com/a/51052247/2352699
Fred Porciúncula

Réponses:

330

Mise en œuvre de la BottomNavigationViewcondition: lorsqu'il y a plus de 3 éléments, utilisez le mode shift.

Pour le moment, vous ne pouvez pas le modifier via l'API existante et la seule façon de désactiver le mode shift est d'utiliser la réflexion.

Vous aurez besoin d'une classe d'aide:

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

Et puis appliquez la disableShiftModeméthode sur votre BottomNavigationView, mais rappelez-vous que si vous gonflez la vue du menu à partir de votre code, vous devez l'exécuter après avoir gonflé.

Exemple d'utilisation:

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

PS.

N'oubliez pas que vous devrez exécuter cette méthode chaque fois que vous modifiez les éléments de menu dans votre BottomNavigationView.

METTRE À JOUR

Vous devez également mettre à jour le fichier de configuration de proguard (par exemple proguard-rules.pro), le code ci-dessus utilise la réflexion et ne fonctionnera pas si proguard obscurcit le mShiftingModechamp.

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

Merci à Muhammad Alfaifi d'avoir signalé ce problème et d'avoir fourni un extrait .

MISE À JOUR 2

Comme Jolanda Verhoef l'a souligné, la nouvelle bibliothèque de support ( 28.0.0-alpha1) ainsi que la nouvelle bibliothèque de composants matériels ( 1.0.0-beta01) offrent une propriété publique qui peut être utilisée pour manipuler le mode de décalage sur 3 éléments de menu.

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

Dans la bibliothèque des composants matériels, cela s'applique également s'il y a 5 éléments de menu.

MISE À JOUR 3

Comme @ThomasSunderland l'a également souligné, vous pouvez définir cette propriété sur false app:itemHorizontalTranslation="false"sans Enabledsuffixe pour désactiver l'animation de décalage.

vous pouvez consulter le guide complet de la mise en forme du BottomNavigation ici

Przemysław Piechota. Kibao
la source
10
**** Proguard :(
Muhammad Alfaifi
17
Le champ sera obscurci donc aucun moyen de changer sa valeur sauf si vous l'excluez dans votre fichier proguard-rules
Muhammad Alfaifi
8
-keepclassmembers class android.support.design.internal.BottomNavigationMenuView {booléen mShiftingMode; }
Muhammad Alfaifi
8
Parfois, je me demande vraiment pourquoi Google impose ses implémentations de vue aux développeurs. Bien qu'il existe 4 options sur l'application Google+ elle-même, cette fonctionnalité simple aurait dû être accessible via une fonction simple si disponible! Un problème similaire était présent avec le TabLayout qui a été corrigé beaucoup plus tard dans la bibliothèque de support. Merci pour cette solution de contournement à Original Replier et @MuhammadAlfaifi pour avoir amélioré cela.
sud007
19
La nouvelle bibliothèque de support (28.0.0-alpha1) prend en charge la modification de ce comportement via l'application: labelVisibilityMode = "labellisé"
Jolanda Verhoef
50

Depuis la bibliothèque de support 28.0.0-alpha1:

<android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled" />
Junbin Deng
la source
1
J'utilise cette version de la bibliothèque de support mais j'obtiens toujours une erreur sur "labelVisibilityMode" introuvable.
Sagar Maiyad
1
Fonctionner correctement. Pas besoin de réfléchir. Merci une tonne
Bhupesh
1
@Riser assurez-vous que vous n'utilisez app:pasandroid:
Carson Holzheimer
28

Pour désactiver l'animation de texte, vous pouvez également l'utiliser dans votre fichier dimens.xml:

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

Vous devrez peut-être également ajouter ceci dans votre manifeste:

tools:override="true"
Pafoïde
la source
Ca ne fonctionne pas. Je crois que je devais simplement ajouter ceci dans /values/dimens.xml?
Rohan Kandwal
10
@RohanKandwal besoin d'ajoutertools:override="true"
Boy
@Boy Merci, je vais l'essayer.
Rohan Kandwal
ne modifiez que la taille du texte.
The Dude
J'ai juste besoin de mettre comme ça sur mon fichier dimens.xml:<dimen name="design_bottom_navigation_active_text_size" tools:ignore="PrivateResource">12sp</dimen>
Fernando Barbosa
22

Vous pouvez maintenant utiliser app:labelVisibilityMode="[labeled, unlabeled, selected, auto]"dans28-alpha

  • labeled gardera toutes les étiquettes visibles.
  • unlabeled affichera uniquement les icônes.
  • selected affichera uniquement l'étiquette de l'élément sélectionné et les éléments de décalage.
  • autochoisira étiqueté ou sélectionné en fonction du nombre d'articles que vous avez. étiqueté pour 1-3 articles et sélectionné pour 3+ articles.
Aidan Laing
la source
1
merci Lunkie! C'est la solution la meilleure et la plus simple pour moi
Gregriggins36
Où ajouter cette ligne de code. J'ai essayé d'ajouter mais il y a une erreur introuvable.
Abdulwahid le
@Abdulwahid, vous pouvez ajouter ceci dans le xml de la barre de navigation inférieure une fois que vous avez la bibliothèque de support 28 ou supérieure
Aidan Laing
@Lunkie merci maintenant, il est clair qu'une fois la bibliothèque de soutien 28
Abdulwahid
17

La réponse de Przemysław dans Kotlin en tant que fonction d'extension

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

Utilisation (avec les extensions Android Kotlin):

bottom_navigation_view.disableShiftMode()
Élégie
la source
Travailler pour kotlin. pourquoi nous devons utiliser cette annotation @SuppressLint ("RestrictedApi") pouvez-vous expliquer les pls?
Ranjith Kumar
11

Travaille pour moi

bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

ou

<android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled" />
UgAr0FF
la source
le mien fonctionnait très bien jusqu'à target = 27 mais à partir de target = 28, il est cassé, le texte n'est plus affiché. Mais setLabelVisibilityMode fait l'affaire pour moi, fonctionne maintenant comme un charme
joke4me
10

Pour désactiver l'animation de texte et réduire la taille de la police, utilisez ceci dans votre fichier dimens.xml:

<dimen name="design_bottom_navigation_text_size">10sp</dimen> 
<dimen name="design_bottom_navigation_active_text_size">10sp</dimen>
Abhishek
la source
On peut Navigate-> File...> design_bottom_navigation_item.xmlpour voir qu'il n'y a pas d' autre moyen.
arekolek
6

METTRE À JOUR

dans la version Android 28 et au- dessus , ils ont changé item.setShiftingMode(false)deitem.setShifting(false)

Aussi ils ont enlevé le champ mShiftingMode

Donc l'utilisation sera

 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
la source
vous pouvez utiliser ce code ci-dessous. @SuppressLint ( "RestrictedApi") de removeShiftMode fun (vue: BottomNavigationView) {val menuView = view.getChildAt (0) comme BottomNavigationMenuView menuView.labelVisibilityMode = LabelVisibilityMode.LABEL_VISIBILITY_LABELED menuView.buildMenuView ()}
Profonde P
5

Comme d'autres l'ont souligné, depuis la bibliothèque de support 28.0.0-alpha1, il est possible:

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

ou vous pouvez le définir par programme .

Remarque: si vous effectuez une mise à niveau à partir d'une ancienne version de la bibliothèque de support, n'oubliez pas d'augmenter la version de compilation du SDK. Vérifiez les versions de la bibliothèque de support ici: Versions de la bibliothèque de support

Cependant, vous pouvez toujours obtenir labelVisibilityMode introuvable message lors de la compilation, si votre application dépend des anciennes versions de la bibliothèque de support de conception. Si tel est le cas, essayez de mettre à niveau vers une version de la dépendance donnée, qui dépend au moins de la version de 28.0.0-alpha1 de la bibliothèque de support de conception. Si ce n'est pas possible, définissez la dépendance explicitement.

Si vous utilisez Gradle

  1. Vous pouvez vérifier vos dépendances en exécutant la tâche des dépendances et en recherchant le numéro de version de com.android.support:design .
  2. Pour ajouter une dépendance de support de conception explicitement dans votre build.gradle :

    implémentation 'com.android.support:design:28.0.0'

Richárd Bogdán
la source
4

Pour une réponse mise à jour en utilisant la valeur par défaut. Mettre à jour vers la dernière bibliothèque de conception

mise en œuvre "com.android.support:design:28.0.0"

et mettez à vos attributs XML BottomNavigationView

app:itemHorizontalTranslationEnabled="false"

vous pouvez le mettre aussi par programmation

bottomNavigationView.setItemHorizontalTranslationEnabled(false);

Vous pouvez trouver la source ici BottomNavigationView

J'espère que cela vous aide.

Lester L.
la source
De quoi est-ce différent app:labelVisibilityMode?
wonsuc
@wonsuc il s'agit de l'animation de l'icône et du texte que l'élément sélectionné anime. Alors que labelVisibilityMode sert à afficher si vous souhaitez afficher l'icône avec du texte ou simplement l'icône à afficher lorsqu'elle est sélectionnée.
Lester L.
3

À votre BottomNavigationViewajouterapp: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>

ce qui donne les résultats suivants

Vue de navigation inférieure Android Désactiver le texte et le décalage

Tout est Vаиітy
la source
3

C'est très simple, il suffit d'ajouter une propriété dans BottomNaviationView

app:labelVisibilityMode="unlabeled"
Nevil Ghelani
la source
2

J'ai eu un comportement étrange avec BottomNavigationView. Lorsque je sélectionnais un élément / fragment qu'il contient, le fragment pousse BottomNavigationView un peu plus bas, de sorte que le texte de BottomNavigationView passe sous l'écran, de sorte que seules les icônes étaient visibles et le texte est masqué en cliquant sur n'importe quel élément.

Si vous êtes confronté à ce comportement étrange, voici la solution. Retirez simplement

android:fitsSystemWindows="true"

dans votre disposition racine de fragment. Retirez simplement ceci et boum! BottomNavigationView fonctionnera bien, maintenant il peut être affiché avec du texte et une icône. J'avais ceci dans ma racine CoordinatorLayout de fragment.

N'oubliez pas non plus d'ajouter

BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);

dans votre activité pour désactiver le mode de changement de vitesse. Bien que ce ne soit pas exactement lié à la question posée, mais je trouve cela utile.

Kishan Solanki
la source
1
@ abbath0767 avez-vous vu le lien ceci? Cela pourrait vous être utile.
Kishan Solanki
Je pensais avoir déjà tout essayé, merci beaucoup, je ne m'attendais pas à trouver directement la réponse que je cherchais.
BekaBot
1
Plaisir @BekaBot
Kishan Solanki
2

Il s'agit d'une bibliothèque tierce que j'utilise et elle dispose de nombreuses options de personnalisation telles que la désactivation du mode shift, l'affichage uniquement des icônes, la définition de la taille des icônes, etc. BottomNavigationViewEx

Pei
la source
2

Pour supprimer complètement les animations:

Si vous souhaitez également vous débarrasser de cette petite animation ennuyeuse de la marge supérieure, vous avez besoin de plus de code de réflexion. Voici la solution complète qui supprime toute animation:

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

Et assurez-vous de l'ajouter à votre fichier de configuration proguard:

-keepclassmembers class android.support.design.internal.BottomNavigationMenuView { 
    boolean mShiftingMode; 
}
-keepclassmembers class android.support.design.internal.BottomNavigationItemView { 
    int mShiftAmount;
}
Fred Porciúncula
la source
Android 9 (niveau d'API 28) introduit de nouvelles restrictions sur l'utilisation d'interfaces non SDK et cela ne fonctionnerait pas si vous ciblez 28. developer.android.com/about/versions/pie/…
ernestkamara
2

mettez à jour votre bibliothèque de support vers 28.0.0.

bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
M Moersalin
la source
1

Si vous utilisez support: design: 28.0.0 ajoutez cette ligne app: labelVisibilityMode = "unabeled" à votre BottomNavigationView

Omar Hassan
la source
0

je veux juste ajouter que ci-dessus cette méthode disableShiftMode ajoute également le code ci-dessous. @SuppressLint ("RestrictedApi")

Aleesha Kanwal
la source
0

https://android.jlelse.eu/disable-shift-label-animation-from-bottom-navigation-android-b42a25dcbffc

1

<com.google.android.material.bottomnavigation.BottomNavigationView
...
app:itemHorizontalTranslationEnabled="false"/>

2

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

3

<resources xmlns:tools="http://schemas.android.com/tools">
<dimen name="design_bottom_navigation_active_text_size"
    tools:override="true">12sp</dimen>

Kreker
la source
-1

Vous pouvez l'utiliser pour afficher du texte et des icônes sur BottomNevigationView pour 3 à 5 éléments et arrêter le décalage.

 app:labelVisibilityMode="labeled"

Mais vous serez confronté à un problème de coupe de texte long sur BottmNevigationView pour 5 éléments. pour cela, j'ai trouvé une bonne solution pour arrêter le décalage du texte ainsi que des icônes de BottomNevigationView. Vous pouvez également arrêter le déplacement du texte ainsi que des icônes sur BottomNevigationView également. Des instantanés de code sont donnés ici.

1. Ajoutez cette ligne de code dans BottomNevigationView comme indiqué

<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. Ajoutez des éléments de menu comme suit: -

 <?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.Ajoutez ce style dans le fichier 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) Ajoutez-les dans le dossier 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>

Je suis l' aide de ces liens et créer un lien .Vous pouvez également obtenir de l' aide get en étudiant ces links.This me aide lot.Hope cela aussi vous aider. Merci....

Rahul Kushwaha
la source