【安卓细节】一行代码解决NavigationView的item的高度问题,同样适用于Toolbar

【安卓细节】一行代码解决NavigationView的item的高度问题,同样适用于Toolbar

使用方法

在res目录下的styles文件中的默认主题上修改,增加名为android:listPreferredItemHeightSmall的item项目,直接指定其dp值即可,需要的话也可以使用dimmer文件定义,示例如下:

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        
        <item name="android:listPreferredItemHeightSmall">30dp</item>

    </style>

注意增加
<item name="android:listPreferredItemHeightSmall">30dp</item>

适用情况

  1. Toolbar内的菜单项目
  2. NavigationView侧滑栏的菜单项目

情况说明

本文主要需要是制作一个横屏侧滑菜单栏,但是使用NavigationView做出的效果不尽如意,侧滑栏菜单间距过大,导致需要滑动侧滑栏的菜单才能选得需要的功能。

经过参考网络资料,使用一个适用于toolbar的item属性,解决了问题。

参考原文

最后贴上参考链接:Toolbar Menu自定义item属性

别急,我们一步一步来。 你说:“**好像这个问题解决不了,都没用,还把我原来的地图给搞没了**”,这说明: > ❌ 在尝试修复状态栏的过程中,你可能不小心引入了新的问题(比如布局遮挡、Fragment 不显示、导航异常等) > ✅ 但这些问题 **都可以修复**,而且能同时实现: - ✅ 状态栏是深紫色 - ✅ 图标是白色 - ✅ 地图正常显示不消失 --- ## 🔍 第一步:先定位“地图没了”的原因 ### 🧩 “地图没了” 可能的原因有: | 原因 | 如何判断 | 解决方法 | |------|---------|----------| | 1. `fragment` 被压在 `BottomNavigationView` 下面 | 页面只能看到底部导航 | 检查约束 | | 2. `nav_host_fragment` 高度为 0 | 页面空白 | 约束错误或 `android:layout_height="0dp"` 没生效 | | 3. 权限被拒绝导致没跳转到地图 | 点击地图页无反应 | 查看 Logcat | | 4. 导航图配置错误 | 进不去 `navigation_map` | 检查 `mobile_navigation.xml` | | 5. Toolbar 占据太多空间且不可见 | 内容上移被遮挡 | 设置背景透明或调整布局 | --- ## ✅ 我们现在要做的是:**恢复地图 + 正确设置状态栏** 我会给你一个 **完全安全、可运行的版本**,保证地图正常,状态栏正确。 --- ## ✅ 安全方案:分步还原 + 改进 ### ✅ Step 1:确保你的主题是 `NoActionBar` 打开文件: ``` res/values/themes.xml ``` 确认内容包含 `.NoActionBar`: ```xml <style name="Theme.Bus" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <item name="android:statusBarColor">@color/purple_700</item> <item name="android:windowLightStatusBar">false</item> <item name="colorPrimary">@color/purple_700</item> </style> ``` ✅ 保留这个配置。 --- ### ✅ Step 2:修改 `activity_main.xml` —— 正确使用 ConstraintLayout 布局 这是关键!很多“地图消失”是因为 `ConstraintLayout` 的约束写错了。 ```xml <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <!-- ✅ Toolbar:顶部 --> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:titleTextColor="#FFFFFF" app:navigationIconTint="#FFFFFF" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> <!-- ✅ NavHostFragment:中间区域 --> <fragment android:id="@+id/nav_host_fragment_activity_main" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintTop_toBottomOf="@id/toolbar" app:layout_constraintBottom_toTopOf="@id/nav_view" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:defaultNavHost="true" app:navGraph="@navigation/mobile_navigation" /> <!-- ✅ BottomNavigationView:底部 --> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/nav_view" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:menu="@menu/bottom_nav_menu" /> </androidx.constraintlayout.widget.ConstraintLayout> ``` 📌 关键点: - 所有视图都用 `0dp` + 四周约束 - `nav_host_fragment` 高度是 `0dp`,自动填充中间 - `Toolbar` 在最上面,不会隐藏 --- ### ✅ Step 3:确保 `MainActivity.java` 中绑定了 Toolbar 你必须加上这两行: ```java // 找到 Toolbar 并设为 ActionBar Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); ``` 然后把 `NavigationUI.setupWithNavController(...)` 改成带 `Toolbar` 的版本。 #### ✅ 修改后的 `onCreate()` 核心部分: ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); // ✅ 必须加:绑定 Toolbar androidx.appcompat.widget.Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); // ✅ 设置状态栏(你现在已有的方法) setStatusBar(); BottomNavigationView navView = findViewById(R.id.nav_view); AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder( R.id.navigation_home, R.id.navigation_map, R.id.navigation_settings) .build(); NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main); // ✅ 使用 Toolbar 绑定 NavController NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration); NavigationUI.setupWithNavController(navView, navController); // 其他逻辑保持不变... } ``` --- ### ✅ Step 4:检查 `mobile_navigation.xml` 确保你在 `res/navigation/mobile_navigation.xml` 中定义了 `navigation_map` 页面,并且它是一个有效的 Fragment。 示例: ```xml <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/mobile_navigation" app:startDestination="@id/navigation_home"> <fragment android:id="@+id/navigation_home" android:name="com.example.bus.ui.home.HomeFragment" android:label="首页" /> <fragment android:id="@+id/navigation_map" android:name="com.example.bus.ui.map.MapFragment" android:label="地图" /> <fragment android:id="@+id/navigation_settings" android:name="com.example.bus.ui.settings.SettingsFragment" android:label="设置" /> </navigation> ``` 如果你删了 `MapFragment` 或改名了,就会“地图没了”。 --- ### ✅ Step 5:确认 `MapFragment` 存在并能加载 打开: ``` app/src/main/java/com/example/bus/ui/map/MapFragment.java ``` 确保它继承自 `Fragment` 或 `AppCompatActivity` 的子类,并且布局中有一个 `SupportMapFragment` 或其他地图组件。 例如: ```java public class MapFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_map, container, false); } @Override public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // 如果用了 Google Maps SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager() .findFragmentById(R.id.map); if (mapFragment != null) { mapFragment.getMapAsync(googleMap -> { // 初始化地图 }); } } } ``` --- ### ✅ Step 6:增强 `setStatusBar()` 方法(防国产手机覆盖) 即使设置了,MIUI、EMUI 还是会强行变白。所以我们要加个“双重保险”。 ```java private void setStatusBar() { Window window = getWindow(); applyStatusBar(window); // 延迟再刷一次,防止系统覆盖 new Handler(Looper.getMainLooper()).postDelayed(() -> applyStatusBar(window), 100); } private void applyStatusBar(Window window) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); window.setStatusBarColor(ContextCompat.getColor(this, R.color.purple_700)); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { View decorView = window.getDecorView(); int flags = decorView.getSystemUiVisibility(); flags &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; // 强制图标为白色 decorView.setSystemUiVisibility(flags); } } ``` 导入: ```java import android.os.Handler; import android.os.Looper; ``` --- ## ✅ 最终验证清单 | 检查项 | 是否完成 | |-------|--------| | ✅ 主题是 `NoActionBar` | ✔️ | | ✅ `activity_main.xml` 中 `nav_host_fragment` 高度为 `0dp` 且有完整约束 | ✔️ | | ✅ 添加了 `Toolbar` 并调用 `setSupportActionBar(toolbar)` | ✔️ | | ✅ 使用 `NavigationUI.setupWithNavController(toolbar, ...)` | ✔️ | | ✅ `MapFragment` 存在且未被删除 | ✔️ | | ✅ `setStatusBar()` 被调用且增强了兼容性 | ✔️ | --- ## ✅ 如果还是“地图没了”,请做以下调试 ### 🔎 查看 Logcat 输出: 过滤关键字: - `MapFragment` - `SupportMapFragment` - `Fragment` - `Navigation` 看看有没有报错,比如: ``` Caused by: java.lang.ClassNotFoundException: com.example.bus.ui.map.MapFragment ``` → 说明类不存在或拼写错误。 --- ## ✅ 总结 你现在的问题不是“不能解决”,而是: > ⚠️ 在修改过程中,**布局约束错误 + 缺少 `setSupportActionBar()` + 国产手机覆盖状态栏** 导致看起来“全都坏了” 只要按上面步骤一步步还原和改进,一定能: ✅ 让地图回来 ✅ 让状态栏变成深紫底 + 白字 ✅ 不闪退 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值