BottomNavigationView始终显示图标和文本标签


125

我正在使用设计支持库版本25中的android.support.design.widget.BottomNavigationView

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

当@ menu / bottom_navigation_main中只有三个操作时,它将始终显示图标和文本标签。

当动作多于三个时,始终显示图标和文本标签的方式是什么?


在您的bottom_navigation_main.xml菜单中,如果您将android:showAsAction =“ ifRoom”更改为每个项目,将其更改为android:showAsAction =“ always”。
Shashank Udupa

不,它没有用。我以前尝试过。
Android开发人员

你能告诉你的菜单xml文件
沙善Udupa

'<?xml version =“ 1.0” encoding =“ utf-8”?> <菜单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“ /> <项目android:id =“ @ + id / action_music” app:showAsAction =“ always” /> <item android:id =“ @ + id / account” android:enabled =“ true” app:showAsAction =“ always” /> </ menu>'
Android开发者

4
在BottomNavigationView中放置app:labelVisibilityMode =“ labeled”。
士文湾

Answers:


325

对于仍在寻找解决方案而又不想依赖第三方库或运行时反射的任何人,支持库28 / Jetpack中的BottomNavigationView本机支持始终具有文本标签。

是您要寻找的方法。

或在XML中, app:labelVisibilityMode="labeled"


我需要哪个库版本?
DaniloDeQueiroz

支持库28-alpha1 +
shaishgandhi

您也可以将可见性模式更改为“自动”,以便仅在按下/聚焦时显示图标文字。代码:app:labelVisibilityMode =“ auto”
肯尼·达比里

你是男人!谢谢您使用最新版本的材料库。
sud007

68

2018年5月8日更新

您可以 app:labelVisibilityMode="labeled" 直接在<android.support.design.widget.BottomNavigationView />

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

不需要以下冗长的解决方案。

上一个答案

我在BottomNavigationView上有一些奇怪的行为。当我在其中选择任何项目/片段时,该片段将BottomNavigationView推低一点,因此BottomNavigationView的文本位于屏幕下方,因此单击任何项​​目时仅可见图标并且隐藏文本。

如果您面对这种奇怪的行为,那么这就是解决方案。只需删除

android:fitsSystemWindows="true"

在片段的根布局中。只需将其卸下,即可繁荣!BottomNavigationView可以正常工作,现在可以用文本和图标显示。我在片段的根CoordinatorLayout中有此选项。

也不要忘记添加

BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);

在您的活动中禁用换档模式。

这是该类:

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

结合STAR_ZERO的答案,解决了我的问题!
Christopher Smit

在通话中disableShiftMode,在课堂上removeShiftMode。除了一点点差异外,您的答案还为我解决了这个问题。我现在有五个菜单项,不移动且带有text + icon。谢谢非常感谢!
Yamakuzure

完善。当底部导航中的项目多于3个时,将显示一种转换模式。使用此功能,您可以禁用该移动,因此带有文本的所有图标会立即显示。
Kishor Bikram Oli

1
这是不受限制的api,并且在支持库版本28. +上不起作用。接受@shaishgandhi答案是更合适的方法。
okarakose

19

在版本25中很难。

试试这个代码。但是我认为这不是一个好的解决方案。

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

在Android Studio中,应添加如下代码:```// noinspection RestrictedApi itemView.setShiftingMode(false); // noinspection RestrictedApi itemView.setChecked(false); ```
Jiezhi.G

4
它仍然在转移物品
CodeToLife

1
完美!同时显示图标和文本。但是切换模式(错误)不起作用。
Minkoo

结合KishanSolanki124的答案解决了我的问题!
Christopher Smit

11

这是Kotlin扩展功能,结合了@STAR_ZERO和@ 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)
        }
    }
}

要使用它:

myBottomNavigation.disableShiftMode()

10

您想要这种效果吗?

点击这里查看图片

如果是这样,我建议您尝试BottomNavigationViewEx


1
您的库很好,而且给人留下深刻的印象,但是我一直想使用25.0.0设计库来实现此功能。不幸的是,这与android设计实践背道而驰
Android开发人员

根据docs中的“固定的底部导航栏”,这不违反Material Design规范。另外,我个人感谢您分享这个很棒的图书馆。
Serg de Adelantado

1
这违反了材料设计规范。如果您阅读提供的文档,则会看到该文档明确显示“如果有四个或五个操作,则仅将非活动视图显示为图标”。
费利佩

8

您可以使用它在BottomNevigationView上同时显示文本和图标

app:labelVisibilityMode="labeled"

如果使用此功能,则可以同时查看图标和文本

<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

您可以直接在以下位置使用app:labelVisibilityMode =“ labeled”

<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

在BottomNavigationView类中,有一个BottomNavigationMenuView字段,在BottomNavigationMenuView中,有一个BottomNavigationItemView []字段,它是底部栏中的项目。

假设n是项数,BottomNavigationMenuView将在BottomNavigationItemView []数组的每个成员上调用BottomNavigationItemView.setShiftingMode(n> 3)。此功能决定行为(始终显示标题或仅在选择时显示标题)。

因此,始终显示标题的方法是尝试调用此方法,您可以使用反射来访问私有字段。

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

这非常好,只需要确保BottomNavigationMenuView也不会移动即可。-> f = menuView.getClass()。getDeclaredField(“ mShiftingMode”); f.setAccessible(true); f.setBoolean(menuView,false);
斯蒂芬·k。

4

一路显示标题。尝试以下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)
    }
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.