SystemUI之NavigationBar导航栏
navigation_bar_window.xml à navigation_bar.xml
[NavigationBarFrame [NavigationBarView [NavigationBarInflaterView ] ] ]
View结构图:
二、代码控制流程
2.1、NavigationBar创建及View添加
StatusBar.java:
start() à createAndAddWindows(result) à makeStatusBarView(result) à createNavigationBar(result) à mNavigationBarController.createNavigationBars(……)
- protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
- createNavigationBar(result);
- ……
- inflateStatusBarWindow();
- }
|
- protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
- mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */, result);
- }
|
NavigationBarController.java:
createNavigationBars(……) à createNavigationBar(……) à
navBar. createView (……)
- void createNavigationBar(Display display, Bundle savedState, RegisterStatusBarResult result) {
- ……
- ……
- NavigationBar navBar = new NavigationBar(context,
- mWindowManager,
- ……
- mUserTracker);
- mNavigationBars.put(displayId, navBar);
- View navigationBarView = navBar.createView(savedState);
- ……
- }
|
NavigationBar.java(Contains logic for a navigation bar view):
- public View createView(Bundle savedState) {
- WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- WindowManager.LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
- ……
- PixelFormat.TRANSLUCENT);
- lp.token = new Binder();
- ……
- lp.setTrustedOverlay();
- NavigationBarFrame frame = (NavigationBarFrame) LayoutInflater.from(mContext).inflate(
- R.layout.navigation_bar_window, null);
- View barView = LayoutInflater.from(frame.getContext()).inflate(
- R.layout.navigation_bar, frame);
- barView.addOnAttachStateChangeListener(this);
- mNavigationBarView = barView.findViewById(R.id.navigation_bar_view);
- mContext.getSystemService(WindowManager.class).addView(frame, lp)
- mContentResolver.registerContentObserver(
- Settings.Secure.getUriFor(Settings.Secure.ASSISTANT),
- false /* notifyForDescendants */, mAssistContentObserver, UserHandle.USER_ALL);
- ……
- return barView;
- }
|
备注 : 导航栏的具体位置在框架DisplayPolicy中根据方向等因素确定:
services\core\java\com\android\server\wm\DisplayPolicy.java
- private int layoutNavigationBar(DisplayFrames displayFrames, Rect contentFrame) {
- ……
- final int rotation = displayFrames.mRotation;
- final int displayHeight = displayFrames.mDisplayHeight;
- final int displayWidth = displayFrames.mDisplayWidth;
- final int navBarPosition = navigationBarPosition(displayWidth, displayHeight, rotation);
- ……
- if (navBarPosition == NAV_BAR_BOTTOM) {
- navigationFrame.top = Math.min(cutoutSafeUnrestricted.bottom, navigationFrame.bottom)
- - getNavigationBarFrameHeight(rotation, uiMode);
- } else if (navBarPosition == NAV_BAR_RIGHT) {
- // Landscape screen; nav bar goes to the right.
- navigationFrame.left = Math.min(cutoutSafeUnrestricted.right, navigationFrame.right)
- - getNavigationBarWidth(rotation, uiMode);
- } else if (navBarPosition == NAV_BAR_LEFT) {
- // Seascape screen; nav bar goes to the left.
- navigationFrame.right = Math.max(cutoutSafeUnrestricted.left, navigationFrame.left)
- + getNavigationBarWidth(rotation, uiMode);
- }
- ……
- return navBarPosition;
- }
|
通过上述代码
1、使用navigation_bar_window和navigation_bar填充布局
2、创建NavigationBarFrame 并且添加到windowManager中
2.2、导航栏图标加载及事件逻辑
2.2.1、布局文件添加
navigation_bar_window.xml:
NavigationBarFrame,对DeadZone功能下的touch事件做了处理。
navigation_bar.xml:
- <com.android.systemui.navigationbar.NavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/navigation_bar_view"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:background="@drawable/system_bar_background">
- <com.android.systemui.navigationbar.NavigationBarInflaterView
- android:id="@+id/navigation_inflater"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipChildren="false"
- android:clipToPadding="false" />
- </com.android.systemui.navigationbar.NavigationBarView>
|
NavigationBarInflaterView:
- protected void onFinishInflate() {
- super.onFinishInflate();
- inflateChildren(); //载导航栏布局文件
- clearViews();
- inflateLayout(getDefaultLayout());
- }
|
- private void inflateChildren() {
- removeAllViews();
- mHorizontal = (FrameLayout) mLayoutInflater.inflate(R.layout.navigation_layout,
- this /* root */, false /* attachToRoot */);
- addView(mHorizontal); //载导0度航栏布局文件
- mVertical = (FrameLayout) mLayoutInflater.inflate(R.layout.navigation_layout_vertical,
- this /* root */, false /* attachToRoot */);
- addView(mVertical); //载导90度航栏布局文件
- updateAlternativeOrder();
- }
|
- protected void inflateLayout(String newLayout) {
- ……
- inflateButtons(start, mHorizontal.findViewById(R.id.ends_group),
- false /* landscape */, true /* start */);
- inflateButtons(start, mVertical.findViewById(R.id.ends_group),
- true /* landscape */, true /* start */);
- inflateButtons(center, mHorizontal.findViewById(R.id.center_group),
- false /* landscape */, false /* start */);
- inflateButtons(center, mVertical.findViewById(R.id.center_group),
- true /* landscape */, false /* start */);
- addGravitySpacer(mHorizontal.findViewById(R.id.ends_group));
- addGravitySpacer(mVertical.findViewById(R.id.ends_group));
- inflateButtons(end, mHorizontal.findViewById(R.id.ends_group),
- false /* landscape */, false /* start */);
- inflateButtons(end, mVertical.findViewById(R.id.ends_group),
- true /* landscape */, false /* start */);
- updateButtonDispatchersCurrentView();
- }
|
- protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape, boolean start) {
- LayoutInflater inflater = landscape ? mLandscapeInflater : mLayoutInflater;
- View v = createView(buttonSpec, parent, inflater);
- ……
- v = applySize(v, buttonSpec, landscape, start);
- parent.addView(v);
- ……
- return v;
- }
|
- View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater) {
- View v = null;
- String button = extractButton(buttonSpec);
- if (LEFT.equals(button)) {
- button = extractButton(NAVSPACE);
- } else if (RIGHT.equals(button)) {
- button = extractButton(MENU_IME_ROTATE);
- }
- if (HOME.equals(button)) {
- v = inflater.inflate(R.layout.home, parent, false);
- } else if (BACK.equals(button)) {
- v = inflater.inflate(R.layout.back, parent, false);
- } else if (RECENT.equals(button)) {
- v = inflater.inflate(R.layout.recent_apps, parent, false);
- } else if
- ……
- return v;
- }
|
1、getDefaultLayout决定导航栏显示哪些控件。
一般情况下是home,recent,back这三个键,如果需要加其他的就在这配置,同时在createView添加对应的布局文件。
2、createView方法创建对应的布局文件,并且添加到导航栏中。
2.2.2、资源文件添加、点击触摸事件
1、NavigationBarView.java(图标资源文件加载)
reloadNavIcons( ) à updateIcons(Configuration.EMPTY) à
2、NavigationBar.java(事件处理)
prepareNavigationBarView()
- private void prepareNavigationBarView() {
- mNavigationBarView.reorient();
- ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton();
- recentsButton.setOnClickListener(this::onRecentsClick);
- recentsButton.setOnTouchListener(this::onRecentsTouch);
- ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
- homeButton.setOnTouchListener(this::onHomeTouch);
- reconfigureHomeLongClick();
- ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton();
- accessibilityButton.setOnClickListener(this::onAccessibilityClick);
- accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
- updateAccessibilityServicesState(mAccessibilityManager);
- ButtonDispatcher imeSwitcherButton = mNavigationBarView.getImeSwitchButton();
- imeSwitcherButton.setOnClickListener(this::onImeSwitcherClick);
- updateScreenPinningGestures();
- }
|
参考链接:
SystemUI虚拟导航键加载流
SystemUI之NavigationBar
SystemUI之NavigationBar导航栏相关推荐
- Framework定制系列(一)-----SystemUI NavigationBar导航栏上滑返回Launcher
1. NavigationBar导航栏上滑解决方案 代码路径:frameworks/base/services/core/java/com/android/server/wm/DisplayPolic ...
- 红橙Darren视频笔记 builder设计模式 navigationbar 导航栏第二版
1.builder设计模式简介 builder的实际应用的典型案例有AlertDialog和OKHttp 例如 // AlertDialogAlertDialog alertDialog = new ...
- 微信小程序自定义navigation-bar导航栏(自适应安卓苹果)
最近在写商城,中途遇到了需要自定义修改导航栏的操作,大概是如下图接过样子的,于是想手写一份,但我发现右上角的分享按钮在不同设备离顶部的距离是不一样的,于是找了下官方划水员写的文档(点这里查看),(⊙o ...
- IOS 学习笔记 Toolbar NavigationBar 导航栏 工具栏
Toolbar使用gif图展示效果图: NavigationBar使用gif效果图 导航栏和工具栏(UIToolbar and NavigationBar) 工具栏和导航栏实际上是有很大差距的,这里放 ...
- 【微信小程序】学习笔记-----navigation-bar导航栏
微信官方文档----小程序 微信小程序底部的导航栏不需要自己画,通过配置即可 先配置list数组,tab的列表 在app.json中与其他项平级,当输入tabBar的时候会自动填补齐全,这里要注意,控 ...
- 基于CarSystemUI实现左侧导航栏NavigationBar及下拉面板定制开发1——Android10智能座舱
文章目录 前言 一.需求说明 二.修改方案 1.基于需求的两种设计构想 2.修改正确的高度及宽度 三.CarSystemUI 1.CarOS框架关于CarSystemUI的介绍 2.替换CarSyst ...
- html导航图片滚动条,CSS实现导航栏底部动态滚动条效果
预习了CSS3部分的新知识,想着在不使用JS的情况下实现导航栏滚动条效果,如下: 实现滚动条效果,其实就是在 标签中让元素的宽度由0变化到100%,代码很简单,如下所示: CSS样式部分: ul.na ...
- Android SystemUI之NavigationBar,导航栏(四)
Android SystemUI系列: 1.Android SystemUI之启动流程(一) 2.Android SystemUI之StatusBar,状态栏(二) 3.Android Syste ...
- java屏蔽虚拟按键代码_Android6.0 源码修改之屏蔽导航栏虚拟按键(Home和RecentAPP)/动态显示和隐藏NavigationBar...
场景分析, 为了完全实现沉浸式效果,在进入特定的app后可以将导航栏移除,当退出app后再次将导航栏恢复.(下面将采用发送广播的方式来移除和恢复导航栏) ps:不修改源码的情况下,简单的沉浸式效果实现 ...
最新文章
- 卷积神经网络(CNN)_相关知识
- python使用方法-Python的使用方法
- 【转】你所不知道的HTML head/ 头标签
- ROS 总结(一):ROS系统框架
- 谈谈主机和存储连接的多路径技术
- 学院派CAD工具箱及CAD调用外部应用程序的方法
- Java加载sklearn训练好的模型进行预测(无法搞定)
- NET问答: 如何在 dynamic 集合上使用 Linq ?
- 命令行下Apache日志统计举例
- java实现语音聊天_java 语音聊天核心代码
- dos批处理命令详解(转)
- 正则表达式 两个符号的字段_Tableau正则提取字段部分内容
- 代码管理学:对于重写,四种人的不同态度
- 表的主键用数字还是UUID
- php圆角的度数计算公式,弧度和角度的换算器(度数换算计算器)
- 当不知轴承型号时如何寻找轴承故障频率_电机轴承的故障诊断与失效分析
- Rosalind第83题:Inferring Genotype from a Pedigree
- 基于O-RAN的无线云网络
- 小日期时间型_利于就业的汽车拆解技术服务师证报名时间、考试流程分几个级别?...
- C#压缩、解压缩文件(夹)(rar、zip)
热门文章
- my visitor
- 计算机类核心期刊排名(国内)
- sshpass报错Host key verification failed
- Python3群聊聊天室
- javaScript搜索框
- 如何用python画散点图矩阵_Python的散点图竟然能画这么好看
- 1036. 跟奥巴马一起编程(15)
- 疾病研究:重症肌无力医师指南
- layui解决数据表格右侧有空白现象
- 修改计算机管理员密码,该怎么改电脑administrator密码