Comment désactiver le mode Maj de BottomNavigationView?

BottomNavigationView ne montre 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, seul le titre de l’élément sur lequel vous avez cliqué est affiché.

entrer la description de l'image ici

L’implémentation de BottomNavigationView a une condition: lorsqu’il y a plus de 3 éléments, utilisez le mode shift.

En ce moment, vous ne pouvez pas le changer via l’API existante et le seul moyen de désactiver le mode shift est d’utiliser la reflection.

Vous aurez besoin d’une classe 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 puis appliquez la méthode disableShiftMode sur votre BottomNavigationView , mais rappelez-vous que si vous BottomNavigationView 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 À JOUR

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

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

Merci Muhammad Alfaifi pour avoir signalé ce problème et fourni des extraits .

MISE À JOUR 2

Comme Jolanda Verhoef l'a souligné, la nouvelle bibliothèque Support ( 28.0.1-alpha1 ) et la nouvelle bibliothèque Material Components ( 1.0.0-beta01 ) offrent une propriété publique permettant de manipuler le mode shifting sur 3 éléments de menu.

  

Dans la bibliothèque de composants, elle s'applique également s'il existe 5 éléments de menu.

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

 12sp 

La réponse de Przemysław dans Kotlin comme fonction d’extension

 @SuppressLint("RessortingctedApi") 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 de Kotlin):

 bottom_navigation_view.disableShiftMode() 

Depuis la bibliothèque de support 28.0.0-alpha1:

  

Vous pouvez maintenant utiliser app: labelVisibilityMode = “[étiqueté, non étiqueté, sélectionné, auto]” dans 28-alpha

étiquetés gardera toutes les étiquettes visibles.

sans étiquette affichera uniquement les icons.

Sélectionné affichera uniquement l’étiquette de l’élément sélectionné et les éléments de décalage.

auto choisira étiqueté ou sélectionné en fonction du nombre d’éléments que vous avez. étiquetés pour 1 à 3 articles et sélectionnés pour 3 articles ou plus.

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

 10sp 10sp 

J’ai eu un comportement bizarre avec BottomNavigationView. Lorsque je sélectionnais un élément / fragment quelconque, le fragment poussait BottomNavigationView un peu plus bas, donc le texte de BottomNavigationView se trouvait sous l’écran. Ainsi, seules les icons étaient visibles et le texte était masqué en cliquant sur un élément.

Si vous faites face à ce comportement étrange, voici la solution. Il suffit de supprimer

 android:fitsSystemWindows="true" 

dans votre disposition racine de fragment. Supprimez simplement ceci et boum! BottomNavigationView fonctionnera correctement, maintenant il peut être affiché avec du texte et une icône. Je l’ai eu dans mon coordinateur racineLayout de fragment.

N’oubliez pas non plus d’append

 BottomNavigationViewHelper.disableShiftMode(bottomNavigationView); 

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

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

Travaille pour moi

 bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED); 

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 reflection. Voici la solution complète qui supprime toute animation:

 @SuppressLint("RessortingctedApi") 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 d'append cela à votre fichier de configuration proguard:

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

je veux juste append qu’au-dessus de cette méthode, disableShiftMode ajoute aussi du code ci-dessous. @SuppressLint (“RessortingctedApi”)