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é.
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" />
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 pouvez maintenant utiliser app:labelVisibilityMode="[labeled, unlabeled, selected, auto]"
dans 28-alpha
labeled
gardera toutes les étiquettes visibles.unlabeled
affichera uniquement les icônes.selected
n'affichera que l'étiquette de l'élément sélectionné et les éléments décalés.auto
va 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.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()
Travaille pour moi
bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
ou
<Android.support.design.widget.BottomNavigationView
app:labelVisibilityMode="labeled" />
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>
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
Pour ajouter explicitement une dépendance de support de conception dans votre build.gradle:
implémentation 'com.Android.support:design:28.0.0'
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.
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());
}
}
}
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.
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
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;
}
À 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
Si vous utilisez support: design: 28.0.0, ajoutez cette application en ligne: labelVisibilityMode = "sans étiquette" à votre BottomNavigationView
C'est très simple, il suffit d'ajouter une propriété dans BottomNaviationView
app:labelVisibilityMode="unlabeled"
mettez à jour votre bibliothèque de support à 28.0.0.
bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
je veux juste ajouter qu'au-dessus de cette méthode, désactiverShiftMode ajoute aussi le code ci-dessous . @ SuppressLint ("RestrictedApi")