100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Android 12系统源码_SystemUI(五)自定义状态栏和导航栏视图

Android 12系统源码_SystemUI(五)自定义状态栏和导航栏视图

时间:2024-05-30 14:12:36

相关推荐

Android 12系统源码_SystemUI(五)自定义状态栏和导航栏视图

前言

前面几篇文章我们具体分析了Android12系统原生的StatusBar和CarStatusBar的启动流程以及视图构建流程,本篇文章我们来自定义实现状态栏和导航栏视图。

一、为系统添加自定义状态栏类

1、修改CarSystemUI项目中的config.xml配置文件的config_systemUIServiceComponentsInclude字段,让CarSystemUI模块默认不是启动CarSystemBar,而是启动我们新建的LPCarSystemBar。

packages/apps/Car/SystemUI/res/values/config.xml

<string-array name="config_systemUIServiceComponentsInclude" translatable="false"><!--<item>com.android.systemui.car.systembar.CarSystemBar</item>--><item>com.lp.systemui.LPCarSystemBar</item><item>com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier</item><item>com.android.systemui.car.window.SystemUIOverlayWindowManager</item><item>com.android.systemui.car.toast.CarToastUI</item><item>com.android.systemui.car.volume.VolumeUI</item><item>com.android.systemui.car.cluster.ClusterDisplayController</item></string-array>

2、在CarSystemUI项目里面新建一个类,并在该类中构建状态栏和导航栏视图。

package/app/Car/SystemUI/src/com/lp/systemui/LPCarSystemBar.java

public class LPCarSystemBar extends SystemUI{private final WindowManager mWindowManager;//顶部状态栏private StatusBarViewHelper mStatusBarViewHelper;//底部Dock栏private DockBarViewHelper mDockBarViewHelper;//添加dagger2注解@Injectpublic LPCarSystemBar(Context context, WindowManager windowManager, StatusBarViewHelper statusBarViewHelper, DockBarViewHelper dockBarViewHelper) {super(context);mWindowManager = windowManager;//状态栏mStatusBarViewHelper = statusBarViewHelper;//底部栏mDockBarViewHelper = dockBarViewHelper;}@Overridepublic void start() {createSystemBar();}private void createSystemBar() {createTopCarSystemBar();//创建顶部栏createBottomCarSystemBar();//创建底部栏}}

3、在修改完config.xml配置之后,SystemUIApplication的startServicesIfNeeded方法便会调用ContextComponentResolver的resolveSystemUI方法,尝试创建LPCarSystemBar对象实例,并调用该对象的start方法。

frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java

public class SystemUIApplication extends Application implementsSystemUIAppComponentFactory.ContextInitializer {private ContextComponentHelper mComponentHelper;private void startServicesIfNeeded(String metricsPrefix, String[] services) {...代码省略...final int N = services.length;for (int i = 0; i < N; i++) {String clsName = services[i];//具体SystemUI组件类的完整路径...代码省略...SystemUI obj = mComponentHelper.resolveSystemUI(clsName);//ComponentHelper的resolveSystemUI方法可以通过类名拿到具体的SystemUI实例对象...代码省略...mServices[i].start();...代码省略...}}}

为了让ContextComponentHelper可以成功获得LPCarSystemBar对象实例,我们还需修改Dagger2组件中的代码。

4、修改CarSystemUIBinder类代码,为Dagger2框架提供LPCarSystemBar对象实例。

packages/apps/Car/SystemUI/src/com/android/systemui/CarSystemUIBinder.java

@Module(includes = {RecentsModule.class, StatusBarModule.class, NotificationsModule.class,KeyguardModule.class, OverlayWindowModule.class, CarNotificationModule.class,QuickControlsEntryPointsModule.class})public abstract class CarSystemUIBinder {// /** Inject Car Navigation Bar. */// @Binds// @IntoMap// @ClassKey(CarSystemBar.class)// public abstract SystemUI bindCarSystemBar(CarSystemBar sysui);/** Inject LPCar Navigation Bar. */@Binds@IntoMap@ClassKey(LPCarSystemBar.class)public abstract SystemUI bindLPCarSystemBar(LPCarSystemBar sysui);}

二、构建自定义系统状态栏

1、新建一个状态栏视图管理类StatusBarViewHelper。

packages/apps/Car/SystemUI/src/com/lp/systemui/StatusBarViewHelper.java

public class StatusBarViewHelper{protected Context mContext;protected View mRootView;//为构造方法添加@Inject注解@Injectpublic StatusBarViewHelper(Context mContext) {this.mContext = mContext;mRootView = LayoutInflater.from(mContext).inflate(R.layout.lp_layout_status_bar_view, null, false);}public View getRootView() {return mRootView;}public void initView() {//初始化视图内容}}

自定义状态栏相关的交互逻辑基本都可以写在StatusBarViewHelper这个类里面,lp_layout_status_bar_view.xml则是自定义状态栏所对应的布局文件,通过修改StatusBarViewHelper和lp_layout_status_bar_view.xml的布局内容,基本就能实现自定义状态栏视图的功能了。另外还需为StatusBarViewHelper的构造方法添加@Inject注解,这样Dagger2在构建LPCarSystemBar对象实例的时候,会通过构造方法为mStatusBarViewHelper属性赋值。

2、LPCarSystemBar和构建状态栏视图相关的代码如下所示。

public class LPCarSystemBar extends SystemUI{private final WindowManager mWindowManager;//顶部状态栏private StatusBarViewHelper mStatusBarViewHelper;private boolean mIsAddStatusBarViewToWindow = false;//添加dagger2注解@Injectpublic LPCarSystemBar(Context context, WindowManager windowManager, StatusBarViewHelper statusBarViewHelper, DockBarViewHelper dockBarViewHelper) {super(context);mWindowManager = windowManager;//状态栏mStatusBarViewHelper = statusBarViewHelper;...代码省略...}@Overridepublic void start() {createSystemBar();}private void createSystemBar() {createTopCarSystemBar();...代码省略...}private void createTopCarSystemBar() {//初始化顶部栏视图内容mStatusBarViewHelper.initView();//把顶部栏添加到窗口上addTopCarSystemBarToWindow();}/*** 把顶部栏添加到窗口上*/private void addTopCarSystemBarToWindow() {if (mIsAddStatusBarViewToWindow) {return;}if (mStatusBarViewHelper != null) {//将顶部栏添加到Window中int statusBarHeight = 88;WindowManager.LayoutParams lpTopSystemBar = new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight,WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL,//WindowManager.LayoutParams.TYPE_STATUS_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);//半透明PixelFormat.TRANSPARENT);//全透明lpTopSystemBar.setTitle("LPCarSystemBar");lpTopSystemBar.providesInsetsTypes = new int[]{InsetsState.ITYPE_STATUS_BAR, InsetsState.ITYPE_TOP_MANDATORY_GESTURES};if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {lpTopSystemBar.setFitInsetsTypes(0);}lpTopSystemBar.windowAnimations = 0;lpTopSystemBar.gravity = Gravity.TOP;mWindowManager.addView(mStatusBarViewHelper.getRootView(), lpTopSystemBar);mIsAddStatusBarViewToWindow = true;}}}

在通过构造方法拿到StatusBarViewHelper对象并赋值给mStatusBarViewHelper之后,LPCarSystemBar的start方法会被调用,我们在该方法中调用createSystemBar方法,该方法会调用createTopCarSystemBar方法来创建状态栏视图,并调用addTopCarSystemBarToWindow方法将构建完成的视图添加到窗口中。

三、构建自定义系统底部栏

1、新建一个底部栏视图管理类DockBarViewHelper。

packages/apps/Car/SystemUI/src/com/lp/systemui/DockBarViewHelper.java

public class DockBarViewHelper{protected Context mContext;protected View mRootView;//为构造方法添加@Inject注解@Injectpublic DockBarViewHelper(Context mContext) {this.mContext = mContext;mRootView = LayoutInflater.from(mContext).inflate(R.layout.lp_layout_dock_bar_view, null, false);}public View getRootView() {return mRootView;}public void initView() {//初始化视图内容}}

自定义底部栏相关的交互逻辑基本都可以写在DockBarViewHelper这个类里面,lp_layout_dock_bar_view.xml则是自定义底部栏所对应的布局文件,通过修改StatusBarViewHelper和lp_layout_status_bar_view.xml的布局内容,基本就能实现自定义状态栏视图的功能了。另外还需为DockBarViewHelper的构造方法添加@Inject注解,这样Dagger2在构建LPCarSystemBar对象实例的时候,会通过构造方法为mDockBarViewHelper属性赋值。

2、LPCarSystemBar和构建底部栏视图相关的代码如下所示。

public class LPCarSystemBar extends SystemUI{private final WindowManager mWindowManager;//底部Dock栏private DockBarViewHelper mDockBarViewHelper;private boolean mIsAddDockBarViewToWindow = false;//添加dagger2注解@Injectpublic LPCarSystemBar(Context context, WindowManager windowManager, StatusBarViewHelper statusBarViewHelper, DockBarViewHelper dockBarViewHelper) {super(context);mWindowManager = windowManager;...代码省略...//底部栏mDockBarViewHelper = dockBarViewHelper;}@Overridepublic void start() {createSystemBar();}private void createSystemBar() {...代码省略...createBottomCarSystemBar();}/*** 创建底部栏*/private void createBottomCarSystemBar() {//添加底部栏视图内容mDockBarViewHelper.initView();//把底部栏添加到窗口上addBottomCarSystemBarToWindow();}/*** 把底部栏添加到窗口上*/private void addBottomCarSystemBarToWindow() {if (mIsAddDockBarViewToWindow) {return;}if (mDockBarViewHelper != null) {//将底部栏添加到Window中int navigationBarHeight = 112;//底部栏高度WindowManager.LayoutParams lpBottomSystemBar = new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, navigationBarHeight,WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,//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);//半透明PixelFormat.TRANSPARENT);//全透明lpBottomSystemBar.setTitle("LPBottomCarSystemBar");lpBottomSystemBar.providesInsetsTypes = new int[]{InsetsState.ITYPE_NAVIGATION_BAR, InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES};if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {lpBottomSystemBar.setFitInsetsTypes(0);}lpBottomSystemBar.windowAnimations = 0;lpBottomSystemBar.gravity = Gravity.BOTTOM;mWindowManager.addView(mDockBarViewHelper.getRootView(), lpBottomSystemBar);mIsAddDockBarViewToWindow = true;}}}

在通过构造方法拿到StatusBarViewHelper对象并赋值给mStatusBarViewHelper之后,LPCarSystemBar的start方法会被调用,我们在该方法中调用createSystemBar方法,该方法会调用createBottomCarSystemBar方法来创建状态栏视图,并调用addBottomCarSystemBarToWindow方法将构建完成的视图添加到窗口中。

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