BottomNavigationView exibe ícones e rótulos de texto o tempo todo


125

Estou usando android.support.design.widget.BottomNavigationView da biblioteca de suporte de design versão 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"/>

Quando existem apenas três ações no @ menu / bottom_navigation_main, ele exibe ícones e rótulos de texto o tempo todo.

Qual é a maneira de exibir ícones e rótulos de texto o tempo todo, quando houver mais de três ações.


No menu bottom_navigation_main.xml, se você tiver android: showAsAction = "ifRoom", altere-o para android: showAsAction = "always" para cada item.
— Shashank Udupa

Não, não funcionou. eu tinha tentado isso antes.
— Desenvolvedor Android

Você pode mostrar seu menu arquivo xml
— 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 / conta" android: enabled = "true" app: showAsAction = "always" /> </menu> '
— Desenvolvedor Android

4
coloque o aplicativo: labelVisibilityMode = "labeled" em BottomNavigationView.
— Shrawan

Respostas:


325

Para quem ainda procura uma solução e não deseja confiar em bibliotecas de terceiros ou reflexão em tempo de execução, o BottomNavigationView na Biblioteca de suporte 28 / Jetpack suporta nativamente sempre a etiqueta de texto.

Este é o método que você está procurando.

Ou em XML, app:labelVisibilityMode="labeled"


qual versão de biblioteca eu preciso?
— DaniloDeQueiroz

biblioteca de suporte 28-alpha1 +
— shaishgandhi

Você também pode alterar o modo de visibilidade para "automático" para exibir o texto do ícone quando pressionado / focado apenas. Código: app: labelVisibilityMode = "auto"
— Kenny Dabiri 26/11/19

Você é o cara! Obrigado, isso funciona com a versão mais recente da Biblioteca de materiais.
— sud007 20/02

68

ATUALIZAÇÃO DE 8 de maio de 2018

Você pode usar app:labelVisibilityMode="labeled" diretamente<android.support.design.widget.BottomNavigationView />

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

Não precisa disso abaixo da solução longa.

RESPOSTA ANTERIOR

Eu tive um comportamento estranho com BottomNavigationView. Quando eu selecionava qualquer item / fragmento, o fragmento empurra o BottomNavigationView um pouco mais para baixo, para que o texto do BottomNavigationView fique abaixo da tela, para que apenas os ícones fiquem visíveis e o texto oculto ao clicar em qualquer item.

Se você está enfrentando esse comportamento estranho, aqui está a solução. Basta remover

android:fitsSystemWindows="true"

no seu layout raiz do fragmento. Basta remover isso e boom! BottomNavigationView funcionará bem, agora pode ser mostrado com texto e ícone. Eu tinha isso na minha raiz CoordinatorLayout do fragmento.

Também não se esqueça de adicionar

BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);

em sua atividade para desativar o modo de mudança.

Aqui está essa 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");
        }
    }
}

Isso, combinado com a resposta de STAR_ZERO, resolveu meu problema!
— Christopher Smit

Na ligação que você tem disableShiftModee na classe removeShiftMode. Além dessa pequena discrepância, sua resposta resolveu o problema para mim. Agora tenho cinco itens de menu sem mudar e com o texto + ícone. Obrigado muito muito!
— Yamakuzure

Perfeito. Quando você tem mais de 3 itens na sua navegação inferior, aparece um modo de mudança. Com isso, você pode desativar essa mudança e, portanto, todos os ícones com texto aparecem ao mesmo tempo.
— Kishor Bikram Oli

1
Esta é uma API irrestrita e não funciona na versão 28 da biblioteca de suporte. A resposta @shaishgandhi aceita é a maneira mais adequada de fazê-lo.
— okarakose

19

É difícil na versão 25.

Experimente este código. Mas acho que não é uma boa solução.

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

No Android Studio, adicione um código como este: `` `// noinspection RestrictedApi itemView.setShiftingMode (false); // noinspection RestrictedApi itemView.setChecked (false); ``
— Jiezhi.G

4
ainda está mudando de itens
— CodeToLife 31/05

1
Perfeito !! exibe ícone e texto. Mas o modo de mudança (falso) não está funcionando.
— Minkoo 30/08

Isso em combinação com a resposta de KishanSolanki124 resolveu meu problema!
— Christopher Smit

11

Aqui está uma função de extensão Kotlin que combina a solução @STAR_ZERO e @ 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)
        }
    }
}

Para usá-lo:

myBottomNavigation.disableShiftMode()

10

Você quer esse efeito?

Clique aqui para ver a imagem

Nesse caso, eu recomendo que você tente BottomNavigationViewEx。


1
Sua biblioteca é um trabalho bom e impressionante, mas eu estava procurando obter essa funcionalidade usando a biblioteca de design 25.0.0 Infelizmente, isso é contra a prática de design do
— Android

Isso não é contra as especificações do Design de materiais, de acordo com a "Barra de navegação inferior fixa" nos documentos . Além disso, meus agradecimentos pessoais por compartilhar esta incrível biblioteca.
— Serg de Adelantado

1
Isso é contra as especificações do Material Design. Se você ler o documento que forneceu, verá que ele diz explicitamente "Se houver quatro ou cinco ações, exiba visualizações inativas apenas como ícones".
— Felipe

8

Você pode usar isso para mostrar texto e ícones em BottomNevigationView

app:labelVisibilityMode="labeled"

Se você estiver usando isso, poderá visualizar o ícone e o texto

<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

Você pode usar o aplicativo: labelVisibilityMode = "labeled" diretamente no

<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

na classe BottomNavigationView, existe um campo BottomNavigationMenuView e, em BottomNavigationMenuView, existe um campo BottomNavigationItemView [], que são os itens na barra inferior.

Diga que n é o número de itens que BottomNavigationMenuView chamará BottomNavigationItemView.setShiftingMode (n> 3) em cada membro da matriz BottomNavigationItemView []. Esta função decide o comportamento (mostrar o título sempre ou somente após a seleção).

portanto, a maneira de mostrar sempre os títulos é tentar chamar esse método e você pode usar a reflexão para acessar os campos particulares.

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

Isso é muito bom, só precisamos garantir que o BottomNavigationMenuView também não seja alterado. -> f = menuView.getClass (). getDeclaredField ("mShiftingMode"); f.setAccessible (verdadeiro); f.setBoolean (menuView, false);
— stephane k.

4

Para mostrar os títulos até o fim. Experimente este código 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)
    }
}

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.