写在前面: SystemUI 是Android原生系统极重要的系统APP,本文介绍如何根据需要在原生三个按键BACK HOME RECENT的基础上,新增新的自定义按键。SystemUI总共分为三个版本:Phone手机、Tablet平板、TV版本。Android13中,Phone、Tablet是一样的。本教程适用SystemUI版本:Android13——>Phone 、Tablet版SystemUI。 注:SystemUI的启动流程,本篇文章不介绍。

一、底部导航栏新增功能按键。

  首先介绍一下Phone、Tablet版的SystemUI的启动路线,看下图:   启动流程中的CentralSurfaces,是我们修改的切入点。打开源码找到CentralSurfacesImpl.java文件,下面我沿着CentralSurfacesImpl.java简单描述一下修改思路,然后贴出完整补丁。

1、frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\CentralSurfacesImpl.java

@Override

public void start() {

. . . . . .

. . . . . .

. . . . . .

createAndAddWindows(result);//这里为入口

. . . . . .

. . . . . .

. . . . . .

}

@Override

public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {

makeStatusBarView(result);//从这里进去创建状态栏、导航栏

mNotificationShadeWindowController.attach();

mStatusBarWindowController.attach();

}

// ================================================================================

// Constructing the view

// ================================================================================

protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {

. . . . . .

. . . . . .

. . . . . .

createNavigationBar(result);//创建导航栏入口

. . . . . .

. . . . . .

. . . . . .

}

protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {

mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */, result);

}

2、frameworks\base\packages\SystemUI\src\com\android\systemui\navigationbar\NavigationBarController.java

public void createNavigationBars(final boolean includeDefaultDisplay,

RegisterStatusBarResult result) {

updateAccessibilityButtonModeIfNeeded();

// Don't need to create nav bar on the default display if we initialize TaskBar.

final boolean shouldCreateDefaultNavbar = includeDefaultDisplay

&& !initializeTaskbarIfNecessary();

Display[] displays = mDisplayManager.getDisplays();

for (Display display : displays) {

if (shouldCreateDefaultNavbar || display.getDisplayId() != DEFAULT_DISPLAY) {

createNavigationBar(display, null /* savedState */, result);

}

}

}

/**

* Adds a navigation bar on default display or an external display if the display supports

* system decorations.

*

* @param display the display to add navigation bar on.

*/

@VisibleForTesting

void createNavigationBar(Display display, Bundle savedState, RegisterStatusBarResult result) {

. . . . . .

. . . . . .

. . . . . .

//从这里分为两个部分

NavigationBar navBar = component.getNavigationBar();//导航栏实例化

navBar.init();//将导航栏添加到屏幕上

. . . . . .

. . . . . .

. . . . . .

}

注:导航栏实例化会去加载导航栏对应的XML,里面默认只有Back|Home|Recent,想要添加新的功能键,第一步就是去修改这个XML;navBar.init()中则是为按键添加图标、绑定点击事件,并最终通过windowManager的addView方法将导航添加到桌面上显示。

完整补丁:

1、xml中新增按钮

  以我的项目分辨率 = 1920x1080、dpi = 320、density = 2来说,对应修改的xml为——>res\values-sw372dp\config.xml 我这里给出的例子,除了原生Back|Home|Recent之外,新增了其它四个按键。

diff --git a/frameworks/base/packages/SystemUI/res/values-sw372dp/config.xml b/frameworks/base/packages/SystemUI/res/values-sw372dp/config.xml

index 07b797a324..3b936766c5 100644

--- a/frameworks/base/packages/SystemUI/res/values-sw372dp/config.xml

+++ b/frameworks/base/packages/SystemUI/res/values-sw372dp/config.xml

@@ -21,5 +21,5 @@

for different hardware and product builds. -->

- left[.25W],back[.5WC];home;recent[.5WC],right[.25W]

+ back;home;recent;volume;comments;whiteboard;collapse

2、NavigationBarInflaterView.java

  inflateLayout函数新增inflateButtons选项、createView函数新增对新按钮描述String的过滤;这个类的功能主要是从上述的xml文件中把所有按键加载进来,并进行过滤操作。

diff --git a/frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java b/frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java

index 59bb2278ed..5724e09a00 100644

--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java

+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java

@@ -60,6 +60,12 @@ public class NavigationBarInflaterView extends FrameLayout

public static final String BACK = "back";

public static final String HOME = "home";

public static final String RECENT = "recent";

+ //xuhao add

+ public static final String VOLUME = "volume";

+ public static final String COMMENTS = "comments";

+ public static final String WHITEBOARD = "whiteboard";

+ public static final String COLLAPSE = "collapse";

+ //

public static final String NAVSPACE = "space";

public static final String CLIPBOARD = "clipboard";

public static final String HOME_HANDLE = "home_handle";

@@ -96,7 +102,7 @@ public class NavigationBarInflaterView extends FrameLayout

private View mLastPortrait;

private View mLastLandscape;

- private boolean mIsVertical;

+ private boolean mIsVertical ;

private boolean mAlternativeOrder;

private OverviewProxyService mOverviewProxyService;

@@ -177,6 +183,7 @@ public class NavigationBarInflaterView extends FrameLayout

void updateButtonDispatchersCurrentView() {

if (mButtonDispatchers != null) {

View view = mIsVertical ? mVertical : mHorizontal;

+ Log.d(TAG,"mIsVertical"+mIsVertical);

for (int i = 0; i < mButtonDispatchers.size(); i++) {

final ButtonDispatcher dispatcher = mButtonDispatchers.valueAt(i);

dispatcher.setCurrentView(view);

@@ -236,34 +243,64 @@ public class NavigationBarInflaterView extends FrameLayout

if (newLayout == null) {

newLayout = getDefaultLayout();

}

- String[] sets = newLayout.split(GRAVITY_SEPARATOR, 3);

- if (sets.length != 3) {

+

+ //xuhao add

+ String[] sets = newLayout.split(GRAVITY_SEPARATOR, 7);

+ if (sets.length != 7) {

Log.d(TAG, "Invalid layout.");

newLayout =

推荐文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: