175

我正在使用设计支持库版本 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 中只有三个操作时,它始终显示图标和文本标签。

当有超过三个动作时,始终显示图标和文本标签的方式是什么。

4

10 回答 10

453

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

是您正在寻找的方法。

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

于 2018-05-26T15:42:08.043 回答
80

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");
        }
    }
}
于 2017-11-21T07:11:55.533 回答
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);
}
于 2016-11-05T15:56:10.870 回答
12

您可以使用它在 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"/>
于 2019-04-11T15:19:54.840 回答
11

这是一个结合了@STAR_ZERO 和@KishanSolanki124 解决方案的Kotlin 扩展函数。

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()
于 2018-05-17T13:58:12.707 回答
10

你想要这个效果吗?

点击这里查看图片

如果是这样,我推荐你试试BottomNavigationViewEx。</p>

于 2016-11-13T04:02:09.940 回答
7

您可以在 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" />
于 2020-03-03T11:38:31.793 回答
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);
        }
于 2016-11-04T04:14:52.257 回答
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)
    }
}
于 2018-01-15T23:34:19.043 回答
2

Alternative to BottomNavigationViewEx: BottomBar

于 2017-11-10T11:14:13.580 回答