BottomNavigationBiew最大限制5个可以解除吗

android的BottomNavigationBiew最大限制5个可以解除吗?更改源码可以实现吗?

Android中的BottomNavigationView确实有一个默认最大限制为5个菜单项,不过这个限制可以被解除,但需要进行一些修改。

解除BottomNavigationView最大限制的方法是使用反射来访问菜单项的私有字段mButtons。该字段包含BottomNavigationItemView对象的数组,这些对象包含BottomNavigationView中的所有菜单项。

使用反射来访问私有字段需要在应用程序的build.gradle文件中加入以下依赖:

dependencies {
    implementation "androidx.legacy:legacy-support-v4:${version}"
}

然后,通过反射间接访问该字段:

import androidx.annotation.NonNull
import androidx.appcompat.widget.BottomNavigationView
import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.view.menu.MenuItemImpl
import com.google.android.material.bottomnavigation.BottomNavigationItemView
import java.lang.reflect.Field
 
fun BottomNavigationView.removeShiftMode() {
    val menuViewField =
        BottomNavigationView::class.java.getDeclaredField("mMenuView")
    menuViewField.isAccessible = true
 
    val menuView = menuViewField.get(this) as MenuView
    val shiftMode = menuViewField.javaClass.getDeclaredField("mShiftingMode")
    shiftMode.isAccessible = true
    shiftMode.setBoolean(menuView, false)
 
    for (i in 0 until menu.childCount) {
        val item = menu.getItem(i) as MenuItemImpl
        item.isExclusiveCheckable = true
    }
 
    menuView.removeAllViews()
    for (i in 0 until menu.size()) {
        val item = menu.getItem(i) as MenuItemImpl
        item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
        val itemView =
            bottomNavigationItemViewInjector(menuView, item, isShifting = false) as BottomNavigationItemView
        menuView.addView(itemView)
    }
}
 
private fun bottomNavigationItemViewInjector(
    parent: ViewGroup,
    menuItemImpl: MenuItemImpl,
    isShifting: Boolean
): View {
    // 首先使用MenuItemCompat来检查和清理MenuItem图标和文本的状态
    val itemView = MenuItemCompat.getActionView(
        parent.context,
        menuItemImpl,
        MenuItemCompat.NO_ID
    )
    var itemParent: ViewGroup = itemView as ViewGroup
    // 最好的做法是使用布局文件来渲染底部导航的MenuItem项
    val inflater = LayoutInflater.from(parent.context)
    val container = BottomNavigationItemView(parent.context)
    container.addView(inflater.inflate(R.layout.design_bottom_navigation_item, container, false))
    val icon: ImageView = container.findViewById(R.id.icon)
    val smallLabel: TextView = container.findViewById(R.id.smallLabel)
    val largeLabel: TextView = container.findViewById(R.id.largeLabel)
    if (itemView == null) {
        container.setIcon(menuItemImpl.icon)
        smallLabel.text = menuItemImpl.title
    } else {
        container.addView(itemView)
        smallLabel.visibility = View.GONE
        icon.visibility = View.GONE
        val title = itemView.findViewById<View>(R.id.title)
        if (title != null) {
            container.addView(title)
            title.layoutParams = createLayoutParamsForTitle(
                container.resources.getDimensionPixelSize(R.dimen.design_bottom_navigation_margin),
                isShifting
            )
        } else {
            smallLabel.visibility = View.VISIBLE
            icon.visibility = View.VISIBLE
            largeLabel.visibility = View.GONE
            container.setIcon(menuItemImpl.icon)
        }
    }
    container.itemPosition = menuItemImpl.itemId and MENU_TYPE_MASK
    if (!TextUtils.isEmpty(menuItemImpl.contentDescription)) {
        container.contentDescription = menuItemImpl.contentDescription
    }
    TooltipCompat.setTooltipText(container, menuItemImpl.tooltipText)
    return container
}

更改BottomNavigationView的源代码可以实现,但并不推荐这样做,因为在应用程序更新时可能会出现问题。另外,修改库文件代码可能违反开源代码的许可协议。因此,最好使用反射来访问私有字段,这是更安全和可靠的方法。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^