如何使平板模式下的BottomNavigationView按钮均匀分布?
问题说明
使用Material库的BottomNavigationView实现底部导航时,平板模式下希望所有导航按钮均匀铺满整个栏宽,而非默认的集中在屏幕中间。当前XML配置如下:
<com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bnvMain" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/light_blue_grey" app:itemIconTint="@color/bottom_nav_color" app:itemTextColor="@color/bottom_nav_color" app:itemBackground="@android:color/transparent" app:itemHorizontalTranslationEnabled="false" app:labelVisibilityMode="labeled" app:menu="@menu/bottom_navigation_menu" />
当前显示效果:导航按钮聚集在屏幕中间区域,两侧留有大量空白;
期望显示效果:所有导航按钮平分底部导航栏宽度,铺满整个屏幕底部。
已尝试配置app:itemHorizontalTranslationEnabled="false"和app:labelVisibilityMode="labeled",但未达到预期效果。
可行解决方案
方法1:代码动态修改布局权重
BottomNavigationView内部的BottomNavigationMenuView是承载导航项的容器,我们可以直接获取该容器,给每个子项设置layout_weight=1,让它们自动均分宽度:
Kotlin 实现
val bnvMain = findViewById<BottomNavigationView>(R.id.bnvMain) val menuView = bnvMain.getChildAt(0) as BottomNavigationMenuView for (i in 0 until menuView.childCount) { val itemView = menuView.getChildAt(i) val params = itemView.layoutParams as LinearLayout.LayoutParams params.weight = 1f itemView.layoutParams = params }
Java 实现
BottomNavigationView bnvMain = findViewById(R.id.bnvMain); BottomNavigationMenuView menuView = (BottomNavigationMenuView) bnvMain.getChildAt(0); for (int i = 0; i < menuView.getChildCount(); i++) { View itemView = menuView.getChildAt(i); LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) itemView.getLayoutParams(); params.weight = 1f; itemView.setLayoutParams(params); }
将这段代码放在Activity的onCreate或Fragment的onViewCreated方法中即可生效。
方法2:封装自定义View(便于多页面复用)
如果多个页面都需要这种均匀分布的导航栏,可以封装一个自定义View,避免重复代码:
class UniformBottomNavView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = com.google.android.material.R.attr.bottomNavigationStyle ) : BottomNavigationView(context, attrs, defStyleAttr) { override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { super.onLayout(changed, left, top, right, bottom) val menuView = getChildAt(0) as BottomNavigationMenuView for (i in 0 until menuView.childCount) { val itemView = menuView.getChildAt(i) val params = itemView.layoutParams as LinearLayout.LayoutParams params.weight = 1f itemView.layoutParams = params } } }
然后在XML中替换原组件:
<com.your.package.name.UniformBottomNavView android:id="@+id/bnvMain" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/light_blue_grey" app:itemIconTint="@color/bottom_nav_color" app:itemTextColor="@color/bottom_nav_color" app:itemBackground="@android:color/transparent" app:itemHorizontalTranslationEnabled="false" app:labelVisibilityMode="labeled" app:menu="@menu/bottom_navigation_menu" />
注意事项
- 确保使用最新版本的Material Components库,避免旧版本API兼容问题;
- 如果导航项数量较多,均分后图标和文字可能出现挤压,可将
labelVisibilityMode改为unlabeled,或调整文字大小优化显示。
内容的提问来源于stack exchange,提问作者Toqgcm
相关产品推荐
相关产品推荐

