BottomNavigationView affiche les icônes et les étiquettes de texte à tout moment


125

J'utilise android.support.design.widget.BottomNavigationView à partir de la bibliothèque de support de conception 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"/>

Lorsqu'il n'y a que trois actions dans @ menu / bottom_navigation_main, il affiche les icônes et les étiquettes de texte à tout moment.

Comment afficher les icônes et les étiquettes de texte à tout moment lorsqu'il y a plus de trois actions.


Dans votre menu bottom_navigation_main.xml, si vous avez android: showAsAction = "ifRoom" changez-le en android: showAsAction = "always" pour chaque élément.
Shashank Udupa

Non, ça n'a pas marché. je l'avais essayé avant.
Développeur Android

Pouvez-vous afficher votre fichier XML de menu
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 =" always "/> <item android: id =" @ + id / action_schedules "app: showAsAction =" always "/> < item android: id = "@ + id / action_music" app: showAsAction = "always" /> <item android: id = "@ + id / account" android: enabled = "true" app: showAsAction = "always" /> </menu> '
Développeur Android

4
placez l'application: labelVisibilityMode = "étiqueté" dans BottomNavigationView.
Shrawan

Réponses:


327

Pour tous ceux qui recherchent toujours une solution et ne veulent pas s'appuyer sur des bibliothèques tierces ou sur une réflexion d'exécution, BottomNavigationView dans Support Library 28 / Jetpack prend en charge nativement toujours avoir une étiquette de texte.

C'est la méthode que vous recherchez.

Ou en XML, app:labelVisibilityMode="labeled"


de quelle version de bibliothèque ai-je besoin?
DaniloDeQueiroz

bibliothèque de support 28-alpha1 +
shaishgandhi

Vous pouvez également changer le mode de visibilité sur "auto" afin d'afficher le texte de l'icône uniquement lorsque vous appuyez / mise au point. Code: app: labelVisibilityMode = "auto"
Kenny Dabiri

Tu es l'homme! Merci que cela fonctionne avec la dernière version de la bibliothèque de matériaux.
sud007

68

MISE À JOUR DU 8 mai 2018

Vous pouvez utiliser app:labelVisibilityMode="labeled" directement dans<android.support.design.widget.BottomNavigationView />

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

Vous n'avez pas besoin de cette solution longue.

RÉPONSE PRÉCÉDENTE

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

dans votre activité pour désactiver le mode de changement de vitesse.

Voici cette classe:

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

Ceci en combinaison avec la réponse de STAR_ZERO a résolu mon problème!
Christopher Smit

Dans l'appel que vous avez disableShiftModeet dans la classe removeShiftMode. En dehors de cette petite divergence, votre réponse a résolu le problème pour moi. J'ai maintenant cinq menuitems sans décalage et avec texte + icône. Merci très bien!
Yamakuzure

Parfait. Lorsque vous avez plus de 3 éléments dans votre navigation du bas que, il apparaît un mode de décalage. En utilisant cela, vous pouvez désactiver ce décalage et donc toutes les icônes avec du texte apparaissent à la fois.
Kishor Bikram Oli

1
Il s'agit d'une API illimitée et ne fonctionne pas sur la version 28 de la bibliothèque de support. +. La réponse @shaishgandhi acceptée est un moyen plus approprié de le faire.
okarakose

19

C'est difficile dans la version 25.

Essayez ce code. Mais je pense que ce n'est pas une bonne solution.

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

Dans Android Studio, devrait ajouter un code comme celui-ci: `` `` // noinspection RestrictedApi itemView.setShiftingMode (false); // non-inspection RestrictedApi itemView.setChecked (false); `` ``
Jiezhi.G

4
il change encore les éléments
CodeToLife

1
Parfait !! affiche à la fois l'icône et le texte. Mais le mode de décalage (faux) ne fonctionne pas.
Minkoo

Ceci en combinaison avec la réponse de KishanSolanki124 a résolu mon problème!
Christopher Smit

11

Voici une fonction d'extension Kotlin qui combine la solution de @STAR_ZERO et de @ KishanSolanki124.

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

Pour l'utiliser:

myBottomNavigation.disableShiftMode()

10

Voulez-vous cet effet?

Cliquez ici pour voir l'image

Si tel est le cas, je vous ai recommandé d'essayer BottomNavigationViewEx


1
Votre bibliothèque est un bon travail et un travail impressionnant Mais je cherchais à obtenir cette fonctionnalité à l'aide de la bibliothèque de conception 25.0.0 Malheureusement, cela va à l'encontre de la pratique de conception
Android

Ce n'est pas contraire aux spécifications de Material Design, selon la "Barre de navigation inférieure fixe" dans la documentation . Aussi, mes remerciements personnels pour le partage de cette superbe bibliothèque.
Serg de Adelantado

1
Ceci est contre les spécifications de conception matérielle. Si vous lisez le document que vous avez fourni, vous verrez qu'il dit explicitement "S'il y a quatre ou cinq actions, n'affichez les vues inactives que sous forme d'icônes".
Felipe

8

Vous pouvez l'utiliser pour afficher du texte et des icônes sur BottomNevigationView

app:labelVisibilityMode="labeled"

Si vous l'utilisez, vous pourrez voir à la fois l'icône et le texte

<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"/>

6

Vous pouvez utiliser app: labelVisibilityMode = "étiqueté" directement dans

<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" />

5

dans la classe BottomNavigationView, il y a un champ BottomNavigationMenuView et dans BottomNavigationMenuView il y a un champ BottomNavigationItemView [], qui correspond aux éléments de la barre inférieure.

Disons que n est le nombre d'éléments, BottomNavigationMenuView appellera BottomNavigationItemView.setShiftingMode (n> 3) sur chaque membre du tableau BottomNavigationItemView []. Cette fonction décide du comportement (afficher le titre toujours ou uniquement lors de la sélection).

donc la façon de toujours afficher les titres est d'essayer d'appeler cette méthode et vous pouvez utiliser la réflexion pour accéder aux champs privés.

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

C'est très bien, nous devons simplement nous assurer que BottomNavigationMenuView ne se déplace pas non plus. -> f = menuView.getClass (). getDeclaredField ("mShiftingMode"); f.setAccessible (vrai); f.setBoolean (menuView, false);
stephane k.

4

Pour afficher les titres jusqu'au bout. Essayez ce code Kotlin:

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.