基于CarSystemUI实现左侧导航栏NavigationBar及下拉面板定制开发1——Android10智能座舱


前言

随着车载智能座舱的不断发展,各种新能源车引领了大屏化趋势,Android系统自8.0以后也专门为车载开发做了设计和分支CarOS,CarOS相对传统的手机OS有很多改变,例如音频控制CarOS使用CarAudioManager直接控制的硬件音量俗称硬音量,传统手机系统使用AudioManager软件控制音量俗称软音量,还有其它汽车周边硬件控制引入了hal开发等等,后续抽时间我会再写一篇文章介绍CarOS音频控制流程和其在车载中的具体应用设计,本篇我们还是按照标题介绍CarSystemUI相关内容。

一、需求说明

公司有智能座舱的开发需求选取的平台是当红的芯驰系列x9m芯片,芯驰芯片主打一芯多屏,一颗芯片同时实现MP5和仪表,具体UI实现参照别克gl8
别克gl8网图
需求:系列图网上查阅可以看到,左边控制栏是在所有界面都要显示包括第三方地图界面(除了倒车界面),倒车的图层等级最高会处理显示到所有图层上面故不考虑倒车的状态

二、修改方案

1.基于需求的两种设计构想

1.按照以前项目经验可以在framework-PhoneWindowManager中将屏幕左侧裁剪出需要的宽度,再在裁剪的区域贴悬浮窗,这种方式我在6.0系统有实现过的案例。

2.用安卓SystemUI自带的导航栏来实现,先要将底部导航栏调到左侧竖直显示。

后有看到CarSystemUI的官网介绍决定选取第二种方式,按照惯例先到网上搜索Android 10 修改导航栏的位置,很容易就查到修改的为位置在这frameworks/base/servicescore/java/com/android/server/wm/DisplayPolicy.java
我们打开这个类里面有个方法:

   @NavigationBarPosition
    int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) {
        String isCustomSystemUI = SystemProperties.get("persist.systemui.custom");
        if ("1".equals(isCustomSystemUI)) {
            return NAV_BAR_LEFT;
        }
        if (navigationBarCanMove() && displayWidth > displayHeight) {
            if (displayRotation == Surface.ROTATION_270) {
                return NAV_BAR_LEFT;
            } else if (displayRotation == Surface.ROTATION_90) {
                return NAV_BAR_RIGHT;
            }
        }
        return NAV_BAR_BOTTOM;
    }

可以看到修改导航栏位置的方法是navigationBarPosition,这个方法里面是通过配置配置于persist.systemui.custom=1来实现左侧显示,当然我习惯性的去百度搜索persist.systemui.custom字段,然后就打开了新大门有个兄弟写了这个需求,一看芯片用的也是芯驰的他用的是芯驰x9h我用的是x9m。
https://blog.csdn.net/u013004758/article/details/121349325?spm=1001.2014.3001.5502
NavigationBar左侧布局方案探索一
用它写的就解决导航栏显示到左侧的问题,以前前辈说编程是一种思想此刻深有体会。
同样的到我用的平台下添加配置:

android/device/semidrive/x9m/common/DeviceCommon.mk
PRODUCT_PROPERTY_OVERRIDES += \
    ro.product.first_api_level=29 \
    ro.adb.secure=0 \
    persist.ipv6.enable=1 \
    ro.bt.bdaddr_path=/vendor/bluetooth/btmac.txt \
    persist.sys.timezone=Asia/Shanghai \
    persist.sys.country=CN \
    persist.sys.language=zh \
	qemu.hw.mainkeys=0 \
	persist.systemui.custom=1

qemu.hw.mainkeys=0作用是显示导航栏
persist.systemui.custom=1导航栏显示到左侧

运行后效果如下图:
在这里插入图片描述

2.修改正确的高度及宽度

按照我司设计图导航栏宽度是130px,状态栏高度是64px

 find ./ -name "*.xml" |xargs grep "status_bar_height"

在android源码下搜索status_bar_height
在这里插入图片描述
找到对应的位置,调试发现状态栏修改android/packages/services/Car/car_product/overlay/frameworks/base/core/res/res/values/dimens.xml里面

 <dimen name="status_bar_height_landscape">64dp</dimen>

是有效的,但是修改导航栏的高度

<dimen name="navigation_bar_height">48dp</dimen>
<dimen name="navigation_bar_height_landscape">48dp</dimen>

两个参数修改不起作用,这里脑海就会浮现那句经典语句:编程是一种思想!!!
用Android studio把机器里面的界面截取出来,用画图工具量一下上面那个截图里面导航栏的宽度97px,那么这时我的编程思想就想到肯定系统哪里把导航栏设置了这个宽度,所以又做了如下操作

 find ./ -name "*.xml" | xargs grep "navigation_bar_height*"

在这里插入图片描述
然后就看到两个对应的96dp(系统密度是160,1px=1dp),把96dp的全部改成130,执行:

  1. 编译目录 frameworks/base/core/res
  2. 编译命令 mm,,编译完成后会在out/target/product/mek_8q/system/framework目录下生成framework-res.apk
  3. 验证 将生成的apk替换掉system/framework/framework-res.apk,重启发现没变化…………,仔细查看带navigation_bar_参数属性发现有这个
    <!-- Width of the navigation bar when it is placed vertically on the screen -->
    <dimen name="navigation_bar_width">48dp</dimen>

看描述绝对是这里,我再改编译然后替换framework-res.apk,重启还是无效果…………

分析既然status_bar_height的高度在android/packages/services/Car/car_product/overlay/frameworks/base/core/res/res/values/dimens.xml里面改有效果,当然我再次去里面改了一下状态栏高度验证有效,那么我把

<dimen name="navigation_bar_width">48dp</dimen>

这个拷贝到这个目录里面试试android/packages/services/Car/car_product/overlay/frameworks/base/core/res/res/values/dimens.xml

    <dimen name="status_bar_height">76dp</dimen>
	<!-- x9m status bar height add by xmc -->
    <dimen name="status_bar_height_landscape">64dp</dimen>
    <dimen name="status_bar_height_portrait">76dp</dimen>
    <dimen name="car_qs_header_system_icons_area_height">76dp</dimen>
	<!-- x9m navigation bar height add by xmc -->
    <dimen name="navigation_bar_height">48dp</dimen>
    <dimen name="navigation_bar_height_landscape">48dp</dimen>
	
    <!-- Width of the navigation bar when it is placed vertically on the screen -->
    <dimen name="navigation_bar_width">130dp</dimen>

编译——替换framework-res.apk——重启OK,效果如下
在这里插入图片描述
用画图工具量了这次宽度是130px 。

会当水击三千里,自信人生二百年。

状态栏及导航栏高度改好以后就是用CarSystemUI替换现在的SystemUI。
替换的原因:
1.原生SystemUI下拉超级丑,下拉一卡一卡的不够流畅
2.之前研究CarOS框架的时候看到基于CarSystemUI做的状态栏和导航栏应用,不但下拉很流畅而且自带导航栏UI可以放到bottom、left、right,这样就省了很多工作量。

三、CarSystemUI

1.CarOS框架关于CarSystemUI的介绍

https://source.android.google.cn/docs/devices/automotive/hmi/system_ui
CarSystemUI介绍地址
需要的可以去这里做深入研究

2.替换CarSystemUI的原因

做这个双屏之前的也是基于Android10同样是芯驰x9m平台开发过一款单屏的MP5的产品,用的就是CarSystemUI实现的状态栏和下拉面板,下拉特别流畅丝滑,具体实现有些复杂,后面文章再展开讲。

最后放一张我们公司现在的智能座舱产品图
在这里插入图片描述


总结

这篇文章讲了SystemUI实现左侧导航栏NavigationBar的前期准备工作,后续有时间我再介绍状态栏及导航如用CarSystemUI何实现定制需求

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要取消 Android 底部导航栏的半透明/毛玻璃效果,可以在 styles.xml 文件中的 AppTheme 样式中添加以下属性: ```xml <item name="android:navigationBarColor">@android:color/transparent</item> <item name="android:windowTranslucentNavigation">false</item> ``` 其中,`android:navigationBarColor` 属性设置为 `@android:color/transparent` 表示将导航栏的颜色设置为透明,`android:windowTranslucentNavigation` 属性设置为 `false` 表示取消导航栏的半透明效果。 完整的 AppTheme 样式如下: ```xml <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- 取消导航栏的半透明效果 --> <item name="android:navigationBarColor">@android:color/transparent</item> <item name="android:windowTranslucentNavigation">false</item> <!-- 其他属性 --> <!-- ... --> </style> ``` 如果想要实现 Android 底部导航栏毛玻璃效果,可以使用 Android 系统提供的 `BlurDrawable` 类来实现。具体实现步骤可以参考以下代码: ```java // 创建一个 BlurDrawable 对象 BlurDrawable blurDrawable = new BlurDrawable(); // 设置模糊半径和颜色 blurDrawable.setBlurRadius(10); blurDrawable.setColor(Color.parseColor("#66000000")); // 将 BlurDrawable 对象设置为导航栏的背景 getWindow().setNavigationBarColor(Color.TRANSPARENT); getWindow().setNavigationBarDividerColor(Color.TRANSPARENT); getWindow().setNavigationBarColor(blurDrawable.getColor()); getWindow().setNavigationBarDividerColor(blurDrawable.getColor()); ``` 其中,`BlurDrawable` 对象的 `setBlurRadius` 方法用于设置模糊半径,`setColor` 方法用于设置毛玻璃颜色。最后将 `BlurDrawable` 对象设置为导航栏的背景即可。 需要注意的是,`BlurDrawable` 类是 Android 11 引入的新类,如果你的应用最低支持 Android 版本不是 11,需要在 build.gradle 文件中添加以下依赖: ```groovy implementation 'androidx.appcompat:appcompat:1.4.0' implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.window:window:1.0.0' ``` 并且在代码中导入以下类: ```java import androidx.appcompat.graphics.drawable.BlurDrawable; import androidx.window.WindowManager; ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值