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的源代码可以实现,但并不推荐这样做,因为在应用程序更新时可能会出现问题。另外,修改库文件代码可能违反开源代码的许可协议。因此,最好使用反射来访问私有字段,这是更安全和可靠的方法。
不知道你这个问题是否已经解决, 如果还没有解决的话: