web-dev-qa-db-fra.com

Comment désactiver le mode Shift BottomNavigationView?

BottomNavigationView n'affiche pas les titres de menus inactifs.

Comment afficher les titres de tous les éléments de menu dans bottomNavigationBar? Le problème est que dans mon cas, seul le titre de l'élément sur lequel vous cliquez est affiché.

 enter image description here

120
Natan Rubinstein

L'implémentation de BottomNavigationView est conditionnée: quand il y a plus de 3 items, utilisez le mode shift.

Pour le moment, vous ne pouvez pas le modifier via une API existante et le seul moyen de désactiver le mode Shift consiste à utiliser la réflexion.

Vous aurez besoin d'un cours d'assistance:

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 appliquez ensuite la méthode disableShiftMode sur votre BottomNavigationView, mais rappelez-vous que si vous gonflez l'affichage du menu à partir de votre code, vous devez l'exécuter après le gonflage.

Exemple d'utilisation:

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

PS.

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

METTRE &AGRAVE; 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 champ mShiftingMode.

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

Merci Muhammad Alfaifi pour avoir signalé ce problème et en fournissant un extrait .

UPDATE 2

Comme Jolanda Verhoef l'a souligné, la nouvelle bibliothèque Support (28.0.1-alpha1) ainsi que la nouvelle bibliothèque Material Components (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 de composants de matériaux, cela s'applique également s'il y a 5 éléments de menu.

Depuis la bibliothèque de support 28.0.0-alpha1:

<Android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled" />
36
Junbin Deng

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>
21
Pafoid

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

  • labeledgardera toutes les étiquettes visibles.
  • unlabeledaffichera uniquement les icônes.
  • selectedn'affichera que l'étiquette de l'élément sélectionné et les éléments décalés.
  • autova choisir étiqueté ou sélectionné en fonction du nombre d'éléments que vous avez. étiqueté pour 1-3 articles et sélectionné pour 3+ articles.
16
Lunkie

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 Kotlin Android):

bottom_navigation_view.disableShiftMode()
16
ElegyD

Travaille pour moi

bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

ou

<Android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled" />
9
UgAr0FF

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>
8
Abhishek

Comme d'autres l'ont souligné, depuis la bibliothèque 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 de passer à la version SDK de compilation . Vérifiez les versions de support libraray ici: Versions de la bibliothèque de support

Cependant, vous pouvez toujours obtenir le message labelVisibilityMode not found lors de la compilation, si votre application dépend d'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 explicitement la dépendance.

Si vous utilisez Gradle

  1. Vous pouvez vérifier vos depdendecies par Exécuter la tâche dependencies et rechercher le numéro de version de com.Android.support:design.
  2. Pour ajouter explicitement une dépendance de support de conception dans votre build.gradle

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

5
Richárd Bogdán

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

mise en oeuvre "com.Android.support:design:28.0.0"

et mettez à vos attributs xml BottomNavigationView

app:itemHorizontalTranslationEnabled="false"

vous pouvez le dire aussi par programme 

bottomNavigationView.setItemHorizontalTranslationEnabled(false);

Vous pouvez trouver la source ici BottomNavigationView

J'espère que cela vous aide.

4
Lester L.

METTRE À JOUR

dans Android sdk version 28 et supérieure, ils ont changéitem.setShiftingMode(false)enitem.setShifting(false)

Ils ont également supprimé le champmShiftingMode

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());
        }
    }
}
3
Narek Hayrapetyan

J'ai eu un comportement étrange avec BottomNavigationView. Lorsque je sélectionnais un élément ou un fragment de celui-ci, le fragment pousse BottomNavigationView un peu plus bas, donc le texte de BottomNavigationView passe en dessous de l'écran, de sorte que seules les icônes sont visibles et le texte caché en cliquant sur un élément.

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

Android:fitsSystemWindows="true"

dans votre disposition racine de fragment. Il suffit de retirer cela et boum! BottomNavigationView fonctionnera correctement, il peut maintenant être affiché avec un texte et une icône. J'ai cela dans ma racine CoordinatorLayout of fragment.

Aussi n'oubliez pas d'ajouter

BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);

dans votre activité pour désactiver le mode décalage . Bien que cela ne soit pas exactement lié à la question posée, je trouve néanmoins cela utile.

2
KishanSolanki124

C’est une bibliothèque tierce que j’utilise et qui comporte de nombreuses options de personnalisation, telles que la désactivation du mode shift, l’affichage des icônes uniquement, la définition de la taille des icônes, etc. . BottomNavigationViewEx

2
Pei

Pour supprimer complètement les animations:

Si vous souhaitez également vous débarrasser de cette petite animation ennuyeuse, 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;
}
2
Fred Porciúncula

À votre BottomNavigationView ajouter app: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 a pour résultat ce qui suit

 Android Bottom Navigation View Disable Text and Shift

1
All Іѕ Vаиітy

Si vous utilisez support: design: 28.0.0, ajoutez cette application en ligne: labelVisibilityMode = "sans étiquette" à votre BottomNavigationView

1
Omar Hassan

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

app:labelVisibilityMode="unlabeled"
1
Nevil Ghelani

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

bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
0
M Moersalin

je veux juste ajouter qu'au-dessus de cette méthode, désactiverShiftMode ajoute aussi le code ci-dessous . @ SuppressLint ("RestrictedApi")

0
Aleesha Kanwal