第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > Android 12 悬浮通知/横幅通知状态栏应用图标显示不全

Android 12 悬浮通知/横幅通知状态栏应用图标显示不全

时间:2022-08-11 20:09:59

相关推荐

Android 12 悬浮通知/横幅通知状态栏应用图标显示不全

先看下问题的表现情况吧

这个模块的实现在SystemUI

这里先列举下与这个模块以及本文要描述的相关代码和资源文件,后面逐个分析

SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java

SystemUI/res/layout/status_bar.xml

SystemUI/res/layout/heads_up_status_bar_layout.xml

SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java

SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java

SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java

CollapsedStatusBarFragment.java

@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,Bundle savedInstanceState) {// 1.1-就是这里加载了状态栏的布局xml: status_bar.xml return inflater.inflate(R.layout.status_bar, container, false);}....../** Initializes views related to the notification icon area. */public void initNotificationIconArea() {// 1.2-这里初始化屏幕显示是左边部分的通知区域,所使用的布局下面2.2会做展示介绍// 注意:这里的布局不是本文问题所说的悬浮通知时状态栏所显示的该通知的图标和应用名的信息,那个布局后面说ViewGroup notificationIconArea = mStatusBar.findViewById(R.id.notification_icon_area);......}

注意,这个类主要是状态栏布局的跟xml的绑定和初始化,initNotificationIconArea 做的呢,也只是没有悬浮/横幅通知时,左边静态展示的那些通知的布局的绑定初始化

然后一开始会思考,当悬浮/横幅通知来的时候,状态栏显示一会就消失的通知图标加应用名信息是不是通过对这里的布局做一个动态的控制呢?

其实不是的,当悬浮/横幅通知来的时候,特有的状态栏通知信息(应用图标+名称)是有单独布局实现的

status_bar.xml

<LinearLayout android:id="@+id/status_bar_contents"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingStart="@dimen/status_bar_padding_start"android:paddingEnd="@dimen/status_bar_padding_end"android:paddingTop="@dimen/status_bar_padding_top"android:orientation="horizontal"><FrameLayoutandroid:layout_height="match_parent"android:layout_width="0dp"android:layout_weight="1"><include layout="@layout/heads_up_status_bar_layout" /><!-- The alpha of the left side is controlled by PhoneStatusBarTransitions, and theindividual views are controlled by StatusBarManager disable flags DISABLE_CLOCK andDISABLE_NOTIFICATION_ICONS, respectively --><LinearLayoutandroid:id="@+id/status_bar_left_side"android:layout_height="match_parent"android:layout_width="match_parent"android:clipChildren="false">......// 2.2-这里就是上面initNotificationIconArea里注释1.2部分所说的xml布局,// 这个布局是非悬浮/横幅 通知时左边静态的通知图标的布局容器,具体的内容网上相关内容很多,这里不再做缀诉<com.android.systemui.statusbar.AlphaOptimizedFrameLayoutandroid:id="@+id/notification_icon_area"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:orientation="horizontal"android:clipChildren="false"/></LinearLayout></FrameLayout>

那么问题来了,那悬浮/横幅通知时,左上角的通知显示区域的布局在哪里呢?

<include layout=“@layout/heads_up_status_bar_layout” />

仔细看上面status_bar.xml,就在里面,这个布局就是悬浮/横幅通知来的时候,状态栏的特有通知的显示布局

heads_up_status_bar_layout.xml

先看布局文件

<com.android.systemui.statusbar.HeadsUpStatusBarViewxmlns:android="/apk/res/android"android:layout_height="match_parent"android:layout_width="match_parent"android:visibility="invisible"android:id="@+id/heads_up_status_bar_view"android:alpha="0"><!-- This is a space just used as a layout and it's not actually displaying anything. We'rerepositioning the statusbar icon to the position where this is laid out when showing thisview. --><Spaceandroid:id="@+id/icon_placeholder"android:layout_width="@dimen/status_bar_icon_drawing_size"android:layout_height="@dimen/status_bar_icon_drawing_size"android:layout_gravity="center_vertical"/><TextViewandroid:id="@+id/text"android:textAppearance="@style/TextAppearance.HeadsUpStatusBarText"android:layout_width="match_parent"android:layout_height="wrap_content"android:singleLine="true"android:ellipsize="marquee"android:fadingEdge="horizontal"android:textAlignment="viewStart"android:paddingStart="6dp"android:layout_weight="1"android:layout_gravity="center_vertical"/></com.android.systemui.statusbar.HeadsUpStatusBarView>

左边的space 作为一个占位控件,用来存放应用图标icon ,下面的TextView 当然就是用来显示应用名称

然后,经过上面的梳理,既然悬浮/横幅通知的显示控件资源已经清晰了,那么控制显示,绑定数据的代码逻辑在哪里呢?

HeadsUpAppearanceController.java

public HeadsUpAppearanceController(NotificationIconAreaController notificationIconAreaController,HeadsUpManagerPhone headsUpManager,NotificationStackScrollLayoutController notificationStackScrollLayoutController,SysuiStatusBarStateController statusBarStateController,KeyguardBypassController keyguardBypassController,KeyguardStateController keyguardStateController,NotificationWakeUpCoordinator wakeUpCoordinator, CommandQueue commandQueue,NotificationPanelViewController notificationPanelViewController, View statusBarView) {this(notificationIconAreaController, headsUpManager, statusBarStateController,keyguardBypassController, wakeUpCoordinator, keyguardStateController,commandQueue, notificationStackScrollLayoutController,notificationPanelViewController,// 3.1-下面的R.id.heads_up_status_bar_view 控件即上面的heads_up_status_bar_layout.xml// R.id.heads_up_status_bar_view 是 heads_up_status_bar_layout.xml根布局的资源idstatusBarView.findViewById(R.id.heads_up_status_bar_view),statusBarView.findViewById(R.id.clock),statusBarView.findViewById(R.id.operator_name_frame),statusBarView.findViewById(R.id.centered_icon_area));}

// 3.2-这个方法实现处理状态栏的数据绑定和显示private void updateTopEntry() {NotificationEntry newEntry = null;if (shouldBeVisible()) {newEntry = mHeadsUpManager.getTopEntry();}NotificationEntry previousEntry = mHeadsUpStatusBarView.getShowingEntry();mHeadsUpStatusBarView.setEntry(newEntry);if (newEntry != previousEntry) {boolean animateIsolation = false;if (newEntry == null) {// no heads up anymore, lets start the disappear animationsetShown(false);animateIsolation = !mIsExpanded;} else if (previousEntry == null) {// We now have a headsUp and didn't have one before. Let's start the disappear// animationsetShown(true);animateIsolation = !mIsExpanded;}// 3.3-这个方法主要是获取显示icon的位置,数据存储在Rect对象中,// 简单来说就是测量占位坑的位置信息,然后把icon精准投进去updateIsolatedIconLocation(false /* requireUpdate */);// 3.4-这里是处理显示的逻辑mNotificationIconAreaController.showIconIsolated(newEntry == null ? null: newEntry.getIcons().getStatusBarIcon(), animateIsolation);}}

针对showIconIsolated()方法的处理流程做个总结

// src/com/android/systemui/statusbar/phone/NotificationIconAreaController.javapublic void showIconIsolated(StatusBarIconView icon, boolean animated) {mNotificationIcons.showIconIsolated(icon, animated);}// src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.javaprivate void updateTopEntry() {......if (newEntry != previousEntry) {......updateIsolatedIconLocation(false /* requireUpdate */);mNotificationIconAreaController.showIconIsolated(newEntry == null ? null: newEntry.getIcons().getStatusBarIcon(), animateIsolation);}}// src/com/android/systemui/statusbar/phone/NotificationIconContainer.javapublic void showIconIsolated(StatusBarIconView icon, boolean animated) {if (animated) {mIsolatedIconForAnimation = icon != null ? icon : mIsolatedIcon;}mIsolatedIcon = icon;updateState();}

后续的逻辑基本就是针对icon的一系列的间距和偏移的计算啥的,一开始觉得问题可能出在这块,但是这块是原生的逻辑,同时也是适用于静态状态栏的通知图标的。期间也尝试修改一些数值,做了测试,无果!

最后本着 在最小影响范围内解决问题,将目光继续聚焦于heads_up_status_bar_layout.xml这个布局文件,修改如下

<com.android.systemui.statusbar.HeadsUpStatusBarViewxmlns:android="/apk/res/android"android:layout_height="match_parent"android:layout_width="match_parent"android:visibility="invisible"android:orientation="horizontal"android:id="@+id/heads_up_status_bar_view"android:alpha="0"><!-- This is a space just used as a layout and it's not actually displaying anything. We'rerepositioning the statusbar icon to the position where this is laid out when showing thisview. --><Spaceandroid:id="@+id/icon_placeholder"android:layout_width="@dimen/status_bar_icon_drawing_size"android:layout_height="@dimen/status_bar_icon_drawing_size"android:layout_marginLeft="16dp"android:layout_gravity="center_vertical"/><!-- <TextViewandroid:id="@+id/text"android:textAppearance="@style/TextAppearance.HeadsUpStatusBarText"android:layout_width="match_parent"android:layout_height="wrap_content"android:singleLine="true"android:ellipsize="marquee"android:fadingEdge="horizontal"android:textAlignment="viewStart"android:paddingStart="6dp"android:layout_weight="1"android:layout_gravity="center_vertical"/> --><TextViewandroid:id="@+id/text"android:textAppearance="@style/TextAppearance.HeadsUpStatusBarText"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="6dp"android:singleLine="true"android:ellipsize="marquee"android:fadingEdge="horizontal"android:layout_gravity="center_vertical"/></com.android.systemui.statusbar.HeadsUpStatusBarView>

至此,问题解决!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。