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.

Desenvolvedor Android
fonte
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"

shaishgandhi
fonte
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");
        }
    }
}
Kishan Solanki
fonte
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);
}
STAR_ZERO
fonte
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()
chetbox
fonte
10

Você quer esse efeito?

Clique aqui para ver a imagem

Nesse caso, eu recomendo que você tente BottomNavigationViewEx

ittianyu
fonte
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"/>
Kumar Ajay AK
fonte
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" />
kishan verma
fonte
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);
        }
wei wang
fonte
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)
    }
}
Harry Zhang
fonte
1

Alternativa para BottomNavigationViewEx : BottomBar

Mateusz Budzisz
fonte