如何隐藏BottomNavigationView菜单项且保留其占位空间?
核心问题梳理
- 使用
navigation.getMenu().removeItem(R.id.composeur):移除菜单项后,剩余项会自动填满底部栏空间,导致位置偏移 - 使用
setVisibility(View.INVISIBLE):暂时隐藏目标项,但点击其他菜单项时,被隐藏的项会重新显示 - 使用
View.GONE:和移除项效果一致,剩余菜单项会移位
可行解决方案
要实现「隐藏菜单项但保留占位、点击其他项不重现」,需要从两个维度处理:仅隐藏菜单项内的图标和文字以保留布局空间,同时拦截菜单刷新时的可见性重置逻辑。
1. 扩展BottomNavigationViewHelper工具类
修改原有工具类,添加隐藏指定项的逻辑,并拦截菜单状态刷新:
static class BottomNavigationViewHelper { // 移除ShiftMode+隐藏指定菜单项 static void removeShiftModeAndHideTargetItem(BottomNavigationView view, final int targetItemId) { BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0); try { // 原有移除ShiftMode的逻辑 Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode"); shiftingMode.setAccessible(true); shiftingMode.setBoolean(menuView, false); shiftingMode.setAccessible(false); for (int i = 0; i < menuView.getChildCount(); i++) { BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i); item.setShifting(false); item.setChecked(item.getItemData().isChecked()); // 定位目标项,仅隐藏内部图标和文字,保留占位 if (item.getItemData().getItemId() == targetItemId) { View icon = item.findViewById(com.google.android.material.R.id.icon); View title = item.findViewById(com.google.android.material.R.id.title); icon.setVisibility(View.INVISIBLE); title.setVisibility(View.INVISIBLE); // 禁用点击事件,避免误触空白占位 item.setClickable(false); item.setEnabled(false); } } // 监听菜单项选中事件,每次切换后重新隐藏目标项,防止被重置 view.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { hideTargetBottomItem(view, targetItemId); // 此处可添加你的页面切换逻辑 return true; } }); } catch (NoSuchFieldException e) { Log.e("ERROR", "找不到指定字段"); } catch (IllegalAccessException e) { Log.e("ERROR", "无法修改字段值"); } } // 单独的隐藏方法,方便重复调用 static void hideTargetBottomItem(BottomNavigationView view, int targetItemId) { BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0); for (int i = 0; i < menuView.getChildCount(); i++) { BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i); if (item.getItemData().getItemId() == targetItemId) { View icon = item.findViewById(com.google.android.material.R.id.icon); View title = item.findViewById(com.google.android.material.R.id.title); icon.setVisibility(View.INVISIBLE); title.setVisibility(View.INVISIBLE); item.setClickable(false); item.setEnabled(false); } } } }
2. 在页面中调用方法
在Activity/Fragment初始化BottomNavigationView后,调用扩展后的方法:
BottomNavigationView bottomNav = findViewById(R.id.your_bottom_nav_id); // 移除ShiftMode同时隐藏指定项 BottomNavigationViewHelper.removeShiftModeAndHideTargetItem(bottomNav, R.id.composeur); // 若不需要移除ShiftMode,直接调用隐藏方法即可 // BottomNavigationViewHelper.hideTargetBottomItem(bottomNav, R.id.composeur);
方案原理
- 仅隐藏菜单项内部的图标和文字控件,不改变整个项的布局空间,因此其他菜单项不会移位
- 禁用目标项的点击和触摸事件,避免用户误触空白占位区域
- 监听菜单项选中事件,每次切换后重新执行隐藏逻辑,防止BottomNavigationView刷新菜单状态时重置控件可见性
内容的提问来源于stack exchange,提问作者Hajar Hosni
相关产品推荐
相关产品推荐

