一.多图标成点

当系统图标区域或者通知图标区域图标过多,而区域不够时,就会将多余的图标隐藏,并显示一个点,如下图所示。

介绍此功能之前先看一下图标的初始化过程,从中可以看到有个config_statusBarIcons参数,这个参数定义了所有的系统图标由低到高显示优先级顺序。

点图标是通过设置图标的状态为STATE_DOT来实现的,在状态更新后会 applyToView,然后在图标类中setVisibleState来刷新图标,大致流程如下图所示。

二.图标反色

我们可以看到当状态栏背景颜色为淡颜色时,状态栏图标会显示成黑色,背景颜色为深颜色时,图标颜色会变为白色。从2.4的类图可以看到,所有的图标类都实现了onDarkChanged方法,此方法就是用来设置图标颜色的。具体过程可以查看下图:

三.StatusBar服务

在使用部分应用的时候,我们经常发现状态栏会不显示部分图标,这部分功能基本上就都是通过statusbar服务实现,此服务是个系统服务,并不对外开放,只有系统应用可以直接调用(三方应用很多是通过反射方式实现),其启动是在SystemServer.java里,如下:

其中实现了很多常用的功能,方便对状态栏进行操作,可以在IStatusBarService.aidl里看到定义了哪些方法。同时android也提供了adb指令来对状态栏进行操作,通过adb shell cmd statusbar help 可以查看当前支持的adb 功能以及功能说明。

四.自定义刘海功能

刘海存在于锁屏页面和解锁状态的状态栏,两种状态下对于刘海的都是类似,在各自的自定义view中通过判断获取的DisplayCutout对象是否为空来判断是否有刘海。DisplayCutout类是用来对刘海处理的特定api,用来获取刘海的信息。

首先通过OverlayCategoryPreferenceController监听加载选中的刘海资源,资源文件路径为framworks/base/packages/overlay/…/res/res/config.xml

前面加载好刘海资源后,在ScreenDecorations的onDisplayChanged方法会监听刘海列表的变化,当选中状态发生变化会调用update方法,之后在pathFromRescource方法绑定刘海资源,在pathAndDisplay-

CutoutFromSpec方法解析刘海资源,主要是config文件中的字符串,config_mainBuiltInDisplayCutout(自定义刘海也是通过修改这个字符串来修改刘海样式),封装成Bounds,里面包含四个Rect,之后在锁屏和解锁状态获取这个资源并进行显示。

解锁状态栏由自定义view-PhoneStatusBar控制,对于刘海的管理主要是在updateLayoutForCutout方法,首先由updateStatusBarHeight方法更新状态栏的高度,之后通过updateCutoutLocation方法更新刘海。

由上可以看到,这里仅控制中间刘海的显示,其实其他类型刘海仅需要控制状态栏的padding参数,避免覆盖数据,在updateSafeInsets方法执行

锁屏状态下由自定义view-KeyguardStatusBarView控制刘海,具体由updateLayoutParamsForCutout方法实现,这里实现和解锁状态下类似。

刘海自定义可以将默认无刘海修改为个性化刘海模式,也可以修改系统预置的刘海样式,其都是通过修改刘海的配置文件config.xml,不同的是默认无刘海模式配置文件在frameworks/base/core/res/res/values/config.xml,其overlay在vendor/qcom/proprietary/commonsys-intf/resource-overlay/lito/Frameworks/res/values/config.xml,默认使用的是overlay下的配置,当overlay没有需要的数据时,才会去读取frameworks下的数据。

如上是一个刘海的配置文件,默认刘海的配置其dimens数据存放在dimens.xml文件中,重要的是string类型的数据填充,这里进行一下举例。

首先需要提供一张图片如下308px*55px

利用png转换svg工具,将图片转成如下格式:

取出path数据放置在上面所述的String类型区域中,由于这个生成的数据是原来像素的10倍,且涉及px与dp的数据类型装换,px=dp*density/160,命令行输入adb shell wm density可以获取density的数值,根据这个比例缩小,这里是是缩小20倍,生成如下数据:

图示M表示绘制的原点,这里的x向左偏移了60,x控制了刘海的水平位置,之后可以通过adb logcat | grep boundingRect 查看数据,

屏幕1200px,中间值为600,所以600-528=672-600=72,位于居中位置,如不居中可以更改M的第一个数据进行偏移。

由于默认配置是无刘海的,所以config_fillMainBuiltInDisplayCutout配置为false,更改为true以黑边填充,由于这个配置在vendor/qcom/proprietary/commonsys-intf/resource-overlay/lito /Frameworks 下,编译直接编这下面的模块,执行make FrameworksResTarget生成FrameworksResTarget.apk,再push进手机。如果修改的是其他类型的刘海样式应该修改编译对应模块,资源路径为frameworks/base/packages/overlay/…,例如长型刘海使用make DisplayCutoutEmulationTallOverlay编译。达到的效果如下:

其中刘海功能在核心类是frameworks\base\core\java\android\view\DisplayCutout.java,通过配置config_mainBuiltInDisplayCutout值来绘制刘海区域(配置方式可以查阅iSupport网站上的文档《Android P自定义刘海_V1.0.pdf》)。这里主要介绍一下状态栏对这一块的显示处理,在之前介绍状态栏场景时有介绍,在锁屏状态栏和状态栏场景下会有刘海布局,所以我们去查看一下PhoneStatusBarView.java和KeyguardStatusBarView.java代码。在PhoneStatusBarView.java中会在updateCutoutLocation里对刘海布局mCutoutSpace进行设置,大致流程如下图,这里面还有一个display_cutout_margin_consumption参数用以调整刘海的宽度,一般是用于物理刘海外围弧度较大时,此时图标可以稍微显示到刘海里而不会被遮挡,达到最大范围的使用状态栏空间的效果。

KeyguardStatusBarView的处理类似,主要是在onApplyWindowInsets方法里通过updateLayoutConsideringCutout来更新刘海视图mCutoutSpace。

状态栏还有一个软件模拟刘海效果的功能(此功能对项目性能有较高要求,很可能会导致闪屏等问题,所以一定要慎重开启,此处只对功能进行介绍),当项目没有物理刘海或者物理刘海有瑕疵时,需要软件来实现,可以配置config_mainBuiltInDisplayCutout后再配置config_fillMainBuiltInDisplayCutout为true,功能的实现是在frameworks\base\packages\SystemUI\src\com\android\systemui\ScreenDecorations.java里,从下面的类图可以看到ScreenDecorations继承了SystemUI,所以启动也是在SystemUIApplication里,其功能实现相对简单, 主要就是通过DisplayInfo.displayCutout获得刘海参数构造DisplayCutouView,将View添加到mOverlay和mBottomOverlay里,

最后通过WindowManager.addView的形式将mOverlay和mBottomOverlay两个图层显示。

五.新增系统图标

系统图标主要分为两类,状态类图标和信号类图标,所以首先要确定添加的是信号类还是状态类图标,然后就可以开始客制化了。例如如何添加反色状态系统图标。

1)配置config_statusBarIcons参数(优先级一般不建议配置太高),添加图片资源文件

2)添加Controller文件ColorInvertionController.java和ColorInversionControllerImpl.java

3)policy里添加相关图标刷新逻辑,反色属于状态类图标,所以加到PhoneStatusBarPolicy里

4)Dependency中创建ColorInvertionController对象。

需要注意的是,修改完后建议测试一下CTS。

六.客制化原有系统图标

由于图标有自动反色的功能,所以不论提供的图标资源是彩色的还是黑白的,都会被强制转色,所以如果需要保持图标的原有颜色就需要进行相应的修改,以下以客制化飞行模式图标为例。

1)修改飞行模式图标资源frameworks\base\packages\SystemUI\res\drawable\stat_sys_airplane_mode.xml

2)修改对应视图文件,飞行模式是StatusBarIconView

3)由于下拉状态栏和锁屏状态栏对statusIcons做了特殊处理,将其添加到TintedIconManager,所以需要再做以下处理。

 需要注意的是,修改完后建议测试一下CTS。

七.如何去掉状态栏的volte图标

此问题根本原因是客户是刘海项目,导致状态栏系统图标显示区域有限,而volte图标过大,导致其他的很多系统图标无法显示,所以提供一种折中的方案,在状态栏不显示volte,下拉状态栏显示volte。结合StatusIconContainer图标显示的逻辑,我们可以在calculateIconTranslations里判断当前控件的宽度大小。由于状态栏图标控件最大不会超过手机宽度的一半,而下拉状态栏明显大于一半,所以可以以手机宽度的1/2为分界点,当宽度大于分界点时允许显示volte,小于时则不显示,核心修改代码如下。

八.左侧通知图标显示不全

此问题是在刘海屏很宽的时候,左侧连一个通知图标的空间都没有,当只有一个通知图标时,通知图标不会自动转成点图标。分析log发现当前情况下firstOverflowIndex一直为-1,根据代码firstOverflowIndex = noOverflowAfter && !forceOverflow ? i - 1 : i;此时noOverflowAfter为true而forceOverflow为false,导致firstOverflowIndex为-1,解决方案为改为firstOverflowIndex = i解决第一个图标无法显示成点问题。

九.测试过程中,下滑测试可进入到状态栏

此问题客户需要实现的是在某些应用界面强制显示成全屏,且不可下拉状态栏。这块主要是WMS模块控制,此功能很多应用(如工厂测试应用)会需要,修改方式如下:

十.monkey测试12小时,无法下拉状态栏

此问题从log可以看到以下信息, 346172 11-20 03:09:23.449   953   953 I sysui_view_visibility: [358,100]但一直有[358,0]log信息打出,表示QSCustomizer界面被展开但一直没有收缩导致状态栏无法下拉,从代码看在QSCustomizer.java的hide函数中添加了mFinishedFetchingTiles判断,当qs没有load好数据之前不能执行hide中的内容。在qs的edit展开时会调用show,并执行了动画(添加了mExpandAnimationListener),展开完毕后会setCustomizing(true),此时NotificationPanelView.java中 mQs.isCustomizing这个条件为true。然后在qs的edit关闭时会调用hide,并且会执行setCustomizing(false),该句代码执行完毕后NotificationPanelView.java中 mQs.isCustomizing这个条件为false。本问题单的操作会导致在qs没有load好数据之前将qs关闭了,导致调用hide函数时没有调用到其中的setCustomizing(false);从而导致下次执行下拉状态栏时NotificationPanelView.java中 mQs.isCustomizing这个条件一直为true,从而导致了无法继续执行touch事件被return掉了,下拉状态栏无法下拉成功。所以需要添加以下修改,将新增的hide中的mFinishedFetchingTiles移动到左上角的返回键的onclick事件中,使用closeQS的方式在调用hide时不对mFinishedFetchingTiles进行判定。

SystemUi状态栏客制化功能和常见问题分析相关推荐

  1. Android SystemUI的客制化 (2)

    本章主要探讨SYstemUI如何将从源码中拷贝出来,放在Android Studio中编译 上前我们了解了Android 源码如何下载,以及对SystemUI有个大概的了解,这期我们主要讲解上期抛出来 ...

  2. android9.0系统systemUI显示客制化

    1.去除下滑通知栏中的多余快捷图标:对于有的代码在framework中的systemUI中修改,但是有的代码则是在vendor下package中的systemUI中修改,mtk-6762  P代码就是 ...

  3. Android 12.0 Launcher客制化指导手册

    主要包含 Launcher3升级变化:小部件变化 . Go版本差异.支持自动生成Work文件夹 . UI客制化 :桌面布局 .布局配置 .预置图标 .图标客制化 .待机界面客制化.应用抽屉客制化 功能 ...

  4. gantt客制化gantt 图标

    项目场景: 客制化gantt 图标 问题描述 客制化gantt 图标 原因分析: 修改任务的图标 gantt 图标修改成小红旗 type=新增的类型即可 解决方案: 修改任务的图标 gantt.tem ...

  5. Magento教程 7:客制化网站

    帮助你的Magento更上一层楼! 架站完成后,我们将分享一些Magento好用的功能.扩充套件.小技巧以及常见的问题. 开启多语言介面 在Magento中,你可以轻松的进行语言切换,只要使用Mage ...

  6. Android 手机按键客制化详解

    在Android 中会有以下5个按键(Back.Home.Menu.Power.Volume)与用户进行交互,Framework 层中实现按键功能,因此,从手机系统定制的角度,可以满足客户的客制化要求 ...

  7. Android 信号格客制化问题处理

    [Android Q] 信号强度客制化代码位置: NR(5G) CellSignalStrengthNr.java updateLevel() LTE MtkSignalStrength.java u ...

  8. 客制化NVRAM的以太网地址

    在使用SN Write写Ethernet MAC过程中出现了以下的错误: ERROR!! Ethernet Mac:MetaResult = SPMETA_DLL::META_LID_INVALID. ...

  9. 客制化键盘键位修改_干电池 支持5设备无线连接 - 高斯ALT71机械键盘拆解评测...

    近一段时间,本人就感觉小型紧凑机械键盘键盘很火,这点我很意外,一直以来都是87键和104键的天下,怎么突然就很火热呢?我真的是LOW.小型紧凑型机械键盘种类很多,有60.61.64.66.67.68. ...

最新文章

  1. 送40本书,人人有份!
  2. RabbitMQ消息发送和接收
  3. JS 控制RadioButtonList 获得上传文件类型后选中
  4. 转载 雨松mono Unity获取游戏对象详解(来自我的长微博)
  5. 蓝牙基础知识进阶——Physical channel
  6. Linux(debian7)操作基础(十二)之文件加密使用指南
  7. C语言的延时程序怎么改,C语言编程,怎么用按键来改变延时的长短?
  8. denyhosts、中文文档乱码、端口占用查询
  9. 利用Python分析航空公司客户价值
  10. ASP.NET 事件(回传)机制
  11. Flash学习资源下载列表
  12. 主线剧情0.0-Linux学习资源大综合
  13. 隧道管廊UWB定位系统解决方案
  14. php 显示连接数据库失败,php数据库连接失败的原因及解决办法
  15. 用 Python 给自己的头像加一个小国旗或者小月饼
  16. 一次硬盘问题引起的服务器宕机
  17. 【matlab 图像处理】 guide 图像去雾系统
  18. 19号笔刷 ps_ps的19号笔刷怎样设置,详细点,最好配点图
  19. BlackBerry应用商店(App World)
  20. GC9110 SOP8封装 5V低成本大电流有刷直流驱动芯片(替代参考LG9110S)

热门文章

  1. 浮点数数据误差eps处理(详细解析)
  2. 对人工智能的法律主体地位的思考
  3. Python流体动力学共形映射库埃特式流
  4. rk3288 设置imx6ull的lcd控制器的寄存器
  5. ChatGPT(GPT3.5) OpenAI官方API正式发布
  6. flash读取程序 msp430_MSP430读写flash程序
  7. selenium篇之半自动发帖机
  8. 搭建MT4/MT5必须知道的事
  9. 相机内存卡照片删除怎么恢复?小伙伴们看过来!
  10. python flask使用jsonify问题处理