Android 9.0 SystemUI 主要视图 SystemBars

SystemBars 是 SystemUI 主要视图,接下来看看它是如何呈现?基于 AOSP 9.0 分析。

SystemBars#start

SystemBars 启动中 mServices[i].start() 将调用 SystemBars.start():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class SystemBars extends SystemUI {
//省略部分代码
private SystemUI mStatusBar;
@Override
public void start() {
if (DEBUG) Log.d(TAG, "start");
createStatusBarFromConfig();
}
//省略部分代码
private void createStatusBarFromConfig() {
if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
final String clsName = mContext.getString(R.string.config_statusBarComponent);
if (clsName == null || clsName.length() == 0) {
throw andLog("No status bar component configured", null);
}
Class<?> cls = null;
try {
cls = mContext.getClassLoader().loadClass(clsName);
} catch (Throwable t) {
throw andLog("Error loading status bar component: " + clsName, t);
}
try {
mStatusBar = (SystemUI) cls.newInstance();
} catch (Throwable t) {
throw andLog("Error creating status bar component: " + clsName, t);
}
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
mStatusBar.start();
if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
}
//省略部分代码
}

这里 config_statusBarComponent 在 AOSP/frameworks/base/packages/SystemUI/res/values/config.xml 里,值为:

1
<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.StatusBar</string>

上面 mStatusBar.start() 通过反射机制 start 了 StatusBar。

StatusBar#start

1
2
3
4
5
6
7
8
9
10
@Override
public void start() {
mGroupManager = Dependency.get(NotificationGroupManager.class);
mVisualStabilityManager = Dependency.get(VisualStabilityManager.class);
mNotificationLogger = Dependency.get(NotificationLogger.class);
//省略部分代码,主要是实例化
//创建并添加视图
createAndAddWindows();
//省略其他代码
}

StatusBar#addStatusBarWindow

看 createAndAddWindows 方法,又调了 addStatusBarWindow:

1
2
3
4
5
6
7
public void createAndAddWindows() {
addStatusBarWindow();
}
private void addStatusBarWindow() {
makeStatusBarView();
//省略其他代码
}

StatusBar#makeStatusBarView

makeStatusBarView 是关键方法,创建 StatusBarView,makeStatusBarView 内容很多,本篇先看布局部分:

1
2
3
4
5
6
7
8
9
protected void makeStatusBarView() {
final Context context = mContext;
updateDisplaySize(); // populates mDisplayMetrics
updateResources();
updateTheme();
//对应布局文件:super_status_bar.xml
inflateStatusBarWindow(context);
//省略其他代码
}

StatusBar#inflateStatusBarWindow

1
2
3
4
protected void inflateStatusBarWindow(Context context) {
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
R.layout.super_status_bar, null);
}

super_status_bar.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<com.android.systemui.statusbar.phone.StatusBarWindowView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:sysui="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.android.systemui.statusbar.BackDropView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
sysui:ignoreRightInset="true"
>
<ImageView android:id="@+id/backdrop_back"
android:layout_width="match_parent"
android:scaleType="centerCrop"
android:layout_height="match_parent" />
<ImageView android:id="@+id/backdrop_front"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:visibility="invisible" />
</com.android.systemui.statusbar.BackDropView>
<com.android.systemui.statusbar.ScrimView
android:id="@+id/scrim_behind"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAccessibility="no"
sysui:ignoreRightInset="true"
/>
<!--解锁,在桌面时状态栏,通知+系统icon-->
<FrameLayout
android:id="@+id/status_bar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ViewStub android:id="@+id/fullscreen_user_switcher_stub"
android:layout="@layout/car_fullscreen_user_switcher"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!--包含锁屏布局和下拉状态栏布局-->
<include layout="@layout/status_bar_expanded"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible" />
<!--下拉全部状态栏亮度布局-->
<include layout="@layout/brightness_mirror" />
<com.android.systemui.statusbar.ScrimView
android:id="@+id/scrim_in_front"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAccessibility="no"
sysui:ignoreRightInset="true"
/>
</com.android.systemui.statusbar.phone.StatusBarWindowView>

视图

下面具体看看视图,有图有真相,更加直观。

桌面

1、CollapsedStatusBarFragment,status_bar.xml,PhoneStatusBarView,折叠状态栏,包含左边时间通知和右边系统 icon
2、NavigationBarFragment,navigation_bar.xml,底部导航栏

下拉状态栏

1、quick_status_bar_expanded_header.xml
1.1、quick_status_bar_header_system_icons.xml,时间和电量
1.2、quick_qs_status_icons.xml,日期和系统 icon
1.3、QuickQSPanel,quick_status_bar_expanded_header.xml,@+id/quick_qs_panel,快捷设置
2、NotificationStackScrollLayout,@+id/notification_stack_scroller,通知
3、status_bar_notification_footer.xml,通知管理和 clear all

下拉全部状态栏

1、quick_settings_brightness_dialog.xml,亮度设置
2、QSPanel,qs_panel.xml,@+id/quick_settings_panel,快捷设置
3、qs_footer_impl.xml,快捷设置排序和设置入口

锁屏

增加锁屏模式为 Swipe:

整个布局,NotificationPanelView,status_bar_expanded.xml
1、KeyguardStatusBarView,keyguard_status_bar.xml ,状态栏
2、KeyguardStatusView,keyguard_status_view.xml ,时间和日期
3、NotificationStackScrollLayout,@+id/notification_stack_scroller,通知
4、KeyguardBottomAreaView,keyguard_bottom_area.xml,底部解锁

结语

好了,这篇结束了,主要学习 StatusBar 相关布局在哪里写了,先有个直观认识。



联系作者

我的微信公众号:吴小龙同学,欢迎关注交流,公号回复关键字「1024」有惊喜哦。