一、定制状态栏
1、SystemUIApplication启动SystemUI组件的关键代码
framework/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
public class SystemUIApplication extends Application implements SysUiServiceProvider {
public void startServicesIfNeeded() {
String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
startServicesIfNeeded(names);
}
private void startServicesIfNeeded(String[] services) {
mServices = new SystemUI[services.length];
final int N = services.length;
for (int i = 0; i < N; i++) {
String clsName = services[i];
Class cls = Class.forName(clsName);
mServices[i] = (SystemUI) cls.newInstance();
mServices[i].start();
}
}
}
frameworks/base/packages/SystemUI/res/values/config.xml
<string-array name="config_systemUIServiceComponents" translatable="false">
<item>com.android.systemui.Dependency</item>
<item>com.android.systemui.util.NotificationChannels</item>
<item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
<item>com.android.systemui.keyguard.KeyguardViewMediator</item>
<item>com.android.systemui.recents.Recents</item>
<item>com.android.systemui.volume.VolumeUI</item>
<item>com.android.systemui.stackdivider.Divider</item>
<item>com.android.systemui.SystemBars</item>
<item>com.android.systemui.usb.StorageNotification</item>
<item>com.android.systemui.power.PowerUI</item>
<item>com.android.systemui.media.RingtonePlayer</item>
<item>com.android.systemui.keyboard.KeyboardUI</item>
<item>com.android.systemui.pip.PipUI</item>
<item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
<item>@string/config_systemUIVendorServiceComponent</item>
<item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
<item>com.android.systemui.LatencyTester</item>
<item>com.android.systemui.globalactions.GlobalActionsComponent</item>
<item>com.android.systemui.ScreenDecorations</item>
<item>com.android.systemui.fingerprint.FingerprintDialogImpl</item>
<item>com.android.systemui.SliceBroadcastRelayHandler</item>
</string-array>
2、SystemBars启动StatusBar组件关键代码
frameworks/base/packages/SystemUI/src/com/android/systemui/SystemBars.java
public class SystemBars extends SystemUI {
...
@Override
public void start() {
createStatusBarFromConfig();
}
private void createStatusBarFromConfig() {
final String clsName = mContext.getString(R.string.config_statusBarComponent);
Class<?> cls = mContext.getClassLoader().loadClass(clsName);
mStatusBar = (SystemUI) cls.newInstance();
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
mStatusBar.start();
}
frameworks/base/packages/SystemUI/res/values/config.xml
<string name="config_statusBarComponent">com.android.systemui.statusbar.phone.StatusBar</string>
3、StatusBar加载布局文件super_status_bar.xml的关键代码
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
public class StatusBar extends SystemUI implements DemoMode,
DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
ColorExtractor.OnColorsChangedListener, ConfigurationListener, NotificationPresenter {
protected StatusBarWindowView mStatusBarWindow;
protected PhoneStatusBarView mStatusBarView;
@Override
public void start() {
createAndAddWindows();
}
public void createAndAddWindows() {
addStatusBarWindow();
}
private void addStatusBarWindow() {
makeStatusBarView();
}
protected void makeStatusBarView() {
final Context context = mContext;
inflateStatusBarWindow(context);
...
FragmentHostManager.get(mStatusBarWindow)
.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {})
.getFragmentManager()
.beginTransaction()
.replace(R.id.status_bar_container, new CollapsedStatusBarFragment(), CollapsedStatusBarFragment.TAG)
.commit();
...
}
protected void inflateStatusBarWindow(Context context) {
mStatusBarWindow = (StatusBarWindowView) View.inflate(context, R.layout.super_status_bar, null);
}
}
frameworks/base/packages/SystemUI/res/layout/super_status_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
xmlns:tools="http://schemas.android.com/tools"
tools:background="#FFFFFF"
android:fitsSystemWindows="true">
<FrameLayout
android:id="@+id/status_bar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.android.systemui.statusbar.phone.StatusBarWindowView>
4、CollapsedStatusBarFragment加载状态栏布局文件status_bar.xml的关键代码
framework/base/package/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
public class CollapsedStatusBarFragment extends Fragment implements CommandQueue.Callbacks {
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.status_bar, container, false);
}
}
framework/base/package/SystemUI/res/layout/status_bar.xml
<?xml version="1.0" encoding="utf-8"?><!--
<com.android.systemui.statusbar.phone.PhoneStatusBarView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/status_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/status_bar_height"
android:accessibilityPaneTitle="@string/status_bar"
android:background="@drawable/system_bar_background"
android:descendantFocusability="afterDescendants"
android:focusable="false"
android:orientation="vertical">
<ImageView
android:id="@+id/notification_lights_out"
android:layout_width="@dimen/status_bar_icon_size"
android:layout_height="match_parent"
android:paddingStart="@dimen/status_bar_padding_start"
android:paddingBottom="2dip"
android:scaleType="center"
android:src="@drawable/ic_sysbar_lights_out_dot_small"
android:visibility="gone"
tools:visibility="visible" />
<LinearLayout
android:id="@+id/status_bar_contents"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingStart="@dimen/status_bar_padding_start"
android:paddingEnd="@dimen/status_bar_padding_end">
<ViewStub
android:id="@+id/operator_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout="@layout/operator_name" />
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<include layout="@layout/heads_up_status_bar_layout" />
<LinearLayout
android:id="@+id/status_bar_left_side"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false">
<com.android.systemui.statusbar.policy.Clock
android:id="@+id/clock"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical|start"
android:paddingStart="@dimen/status_bar_left_clock_starting_padding"
android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.StatusBar.Clock" />
<com.android.systemui.statusbar.AlphaOptimizedFrameLayout
android:id="@+id/notification_icon_area"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:clipChildren="false"
android:orientation="horizontal" />
</LinearLayout>
</FrameLayout>
<android.widget.Space
android:id="@+id/cutout_space_view"
android:layout_width="0dp"
android:layout_height="match_parent"
android:gravity="center_horizontal|center_vertical" />
<com.android.keyguard.AlphaOptimizedLinearLayout
android:id="@+id/system_icon_area"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical|end"
android:orientation="horizontal">
<include layout="@layout/system_icons" />
</com.android.keyguard.AlphaOptimizedLinearLayout>
</LinearLayout>
<ViewStub
android:id="@+id/emergency_cryptkeeper_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout="@layout/emergency_cryptkeeper_text" />
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
二、定制导航栏
1、StatusBar创建导航栏
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
public class StatusBar extends SystemUI implements DemoMode,
DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
ColorExtractor.OnColorsChangedListener, ConfigurationListener, NotificationPresenter {
private NavigationBarFragment mNavigationBar;
private View mNavigationBarView;
protected void makeStatusBarView() {
...
boolean showNav = mWindowManagerService.hasNavigationBar();
if (showNav) {
createNavigationBar();
}
...
}
protected void createNavigationBar() {
mNavigationBarView = NavigationBarFragment.create(mContext, (tag, fragment) -> {
mNavigationBar = (NavigationBarFragment) fragment;
if (mLightBarController != null) {
mNavigationBar.setLightBarController(mLightBarController);
}
mNavigationBar.setCurrentSysuiVisibility(mSystemUiVisibility);
});
}
2、NavigationBarFragment加载状态栏布局文件status_bar.xml的关键代码
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
public class NavigationBarFragment extends Fragment implements Callbacks {
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.navigation_bar, container, false);
}
}
framework/base/package/SystemUI/res/layout/navigation_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.statusbar.phone.NavigationBarView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="@drawable/system_bar_background">
<com.android.systemui.statusbar.phone.NavigationBarInflaterView
android:id="@+id/navigation_inflater"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.android.systemui.statusbar.phone.NavigationBarView>
三、车载导航栏
1.1、车载状态栏类所对应的关键代码
com.android.systemui.statusbar.car.CarStatusBar.java
public class CarStatusBar extends StatusBar implements
CarBatteryController.BatteryViewHandler {
...
@Override
protected void createNavigationBar() {
mShowBottom = mContext.getResources().getBoolean(R.bool.config_enableBottomNavigationBar);
...
buildNavBarWindows();
buildNavBarContent();
attachNavBarWindows();
}
private void buildNavBarWindows() {
if (mShowBottom) {
mNavigationBarWindow = (ViewGroup) View.inflate(mContext,
R.layout.navigation_bar_window, null);
}
...
}
private void buildNavBarContent() {
if (mShowBottom) {
buildBottomBar((mDeviceIsProvisioned) ? R.layout.car_navigation_bar :
R.layout.car_navigation_bar_unprovisioned);
}
...
}
private void buildBottomBar(int layout) {
View.inflate(mContext, layout, mNavigationBarWindow);
mNavigationBarView = (CarNavigationBarView) mNavigationBarWindow.getChildAt(0);
mNavigationBarView.setStatusBar(this);
}
private void attachNavBarWindows() {
if (mShowBottom) {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
lp.setTitle("CarNavigationBar");
lp.windowAnimations = 0;
mWindowManager.addView(mNavigationBarWindow, lp);
}
}
@Override
public void destroy() {
...
if (mNavigationBarWindow != null) {
mWindowManager.removeViewImmediate(mNavigationBarWindow);
mNavigationBarView = null;
}
...
}
...
@Override
public View getNavigationBarWindow() {
return mNavigationBarWindow;
}
}
1.2、车载状态栏所对应的布局文件
framework/base/package/SystemUI/res/layout/navigation_bar_window.xml
<com.android.systemui.statusbar.phone.NavigationBarFrame
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_bar_frame"
android:layout_height="match_parent"
android:layout_width="match_parent">
</com.android.systemui.statusbar.phone.NavigationBarFrame>
2.1、车载导航栏所对应的类的关键代码
com.android.systemui.statusbar.car.CarNavigationBarView
class CarNavigationBarView extends LinearLayout {
private View mNavButtons;
private AlphaOptimizedImageButton mNotificationsButton;
private CarStatusBar mCarStatusBar;
private Context mContext;
private View mLockScreenButtons;
public CarNavigationBarView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
@Override
public void onFinishInflate() {
mNavButtons = findViewById(R.id.nav_buttons);
mLockScreenButtons = findViewById(R.id.lock_screen_nav_buttons);
mNotificationsButton = findViewById(R.id.notifications);
if (mNotificationsButton != null) {
mNotificationsButton.setOnClickListener(this::onNotificationsClick);
}
View mStatusIcons = findViewById(R.id.statusIcons);
if (mStatusIcons != null) {
StatusBarIconController.DarkIconManager mDarkIconManager =
new StatusBarIconController.DarkIconManager(
mStatusIcons.findViewById(R.id.statusIcons));
mDarkIconManager.setShouldLog(true);
Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager);
}
}
void setStatusBar(CarStatusBar carStatusBar) {
mCarStatusBar = carStatusBar;
}
protected void onNotificationsClick(View v) {
mCarStatusBar.togglePanel();
}
public void showKeyguardButtons() {
if (mLockScreenButtons == null) {
return;
}
mLockScreenButtons.setVisibility(View.VISIBLE);
mNavButtons.setVisibility(View.GONE);
}
public void hideKeyguardButtons() {
if (mLockScreenButtons == null) {
return;
}
mNavButtons.setVisibility(View.VISIBLE);
mLockScreenButtons.setVisibility(View.GONE);
}
}
2.2、车载导航栏所对应的布局文件
framework/base/package/SystemUI/res/layout/navigation_bar_window.xml
<com.android.systemui.statusbar.car.CarNavigationBarView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="@drawable/system_bar_background">
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal"
android:clipChildren="false"
android:clipToPadding="false"
android:id="@+id/nav_buttons"
android:animateLayoutChanges="true">
</LinearLayout>
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal"
android:id="@+id/lights_out"
android:visibility="gone">
</LinearLayout>
</com.android.systemui.statusbar.car.CarNavigationBarView>
|