BottomNavigationView 布局损坏,当以编程方式添加菜单项时

BottomNavigationView layout broken, when add menu items programmatically

出于某种原因,BottomNavigationView 在布局中存在视觉错误。有谁知道有什么办法可以解决它?单击任何按钮后或我将应用程序最小化并恢复后问题解决。

它应该是这样的:

通过 XML 展开菜单时一切正常。

<com.google.android.material.bottomnavigation.BottomNavigationView
        android:layout_width="match_parent"
        android:layout_height="56dp"
        ...
        app:menu="@menu/bottom_navigation_4_game" />

当我以编程方式添加 MenuItem 时:

navigationView.menu.clear()
navigationView.inflateMenu(R.menu.bottom_navigation4)

我们可能在LayoutInspector中看到,其实有5个item,但是有两个被overlay了,看不到:

问题可能出在BottomNavigationMenuView。在 LayoutInspector getWidth() returns 0. 使视图无效没有帮助。

如果您尝试创建包含 2 个不同菜单项集的动态 BottomNavigationView,

因此,不要动态添加菜单项,而是使用 2 种不同的 xml 布局(定义了 2 种不同的 app:menu 属性),并根据条件在它们之间切换然后代码。

所以,XML 看起来像这样:

<BottomNavigationView
                android:id="@+id/bottom_navigation"
                android:layout_width="match_parent"
                android:layout_height="@dimen/bottom_bar_height"
                app:elevation="8dp"
                app:itemIconTint="?attr/nav_item_color_state_red"
                app:itemTextColor="?attr/nav_item_color_state_red"
                app:labelVisibilityMode="labeled"
                app:menu="@menu/bottom_navigation_1" />


            <BottomNavigationView
                android:id="@+id/bottom_navigation_mini_player"
                android:layout_width="match_parent"
                android:layout_height="@dimen/bottom_bar_height"
                app:elevation="8dp"
                app:itemIconTint="?attr/nav_item_color_state_red"
                app:itemTextColor="?attr/nav_item_color_state_red"
                app:labelVisibilityMode="labeled"
                app:menu="@menu/bottom_navigation_2" />

我在应用程序中发现了一个奇怪的代码块,这是罪魁祸首。事实证明,TransitionManager 并未使用 ConstraintLayout 结束其转换。这段代码:updateConstraints {} 在动态更改 BottomNavigationView 后立即被调用,因此我猜它的子视图转换被中断了。

private fun updateConstraints(f: ConstraintSet.() -> Unit) {
    TransitionManager.beginDelayedTransition(root)
    val set = ConstraintSet().apply { clone(root) }
    set.f()
    set.applyTo(root)
}