hmrshkk 2023-04-02 20:13 采纳率: 57.1%
浏览 19
已结题

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

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

  • 写回答

2条回答 默认 最新

  • 瞬间的醒悟 2023-04-02 21:03
    关注

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月24日
  • 已采纳回答 4月24日
  • 创建了问题 4月2日

悬赏问题

  • ¥15 使用aytodl训练,希望有直接运行的代码(关键词-数据集)
  • ¥20 关于线性结构的问题:希望能从头到尾完整地帮我改一下,困扰我很久了
  • ¥20 设计一个二极管稳压值检测电路
  • ¥15 内网办公电脑进行向日葵
  • ¥15 如何输入双曲线的参数a然后画出双曲线?我输入处理函数加上后就没有用了,不知道怎么回事去掉后双曲线可以画出来
  • ¥50 WPF Lidgren.Network.Core2连接问题
  • ¥15 soildworks装配体的尺寸问题
  • ¥100 有偿寻云闪付SDK转URL技术
  • ¥30 基于信创PC发布的QT应用如何跨用户启动后输入中文
  • ¥20 非root手机,如何精准控制手机流量消耗的大小,如20M