种类
Android10 默认的系统导航有三种:
1.两个按钮的
2.三个按钮的
3.手势
它们分别对应三个包名
frameworks/base/packages/overlays/NavigationBarMode2ButtonOverlay
frameworks/base/packages/overlays/NavigationBarMode3ButtonOverlayframeworks/base/packages/overlays/NavigationBarModeGesturalOverlay
在设置里切换导航模式的时候会执行SystemNavigationGestureSettings.java的如下方法:
static void setCurrentSystemNavigationMode(Context context, IOverlayManager overlayManager,
String key) {
switch (key) {
case KEY_SYSTEM_NAV_GESTURAL:
int sensitivity = getBackSensitivity(context, overlayManager);
setNavBarInteractionMode(overlayManager, BACK_GESTURE_INSET_OVERLAYS[sensitivity]);
break;
case KEY_SYSTEM_NAV_2BUTTONS:
setNavBarInteractionMode(overlayManager, NAV_BAR_MODE_2BUTTON_OVERLAY);
break;
case KEY_SYSTEM_NAV_3BUTTONS:
setNavBarInteractionMode(overlayManager, NAV_BAR_MODE_3BUTTON_OVERLAY);
break;
}
}
private static void setNavBarInteractionMode(IOverlayManager overlayManager,
String overlayPackage) {
try {
overlayManager.setEnabledExclusiveInCategory(overlayPackage, USER_CURRENT);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
-----------------------------------------------------------------------------------
String NAV_BAR_MODE_3BUTTON_OVERLAY = "com.android.internal.systemui.navbar.threebutton";
String NAV_BAR_MODE_2BUTTON_OVERLAY = "com.android.internal.systemui.navbar.twobutton";
String NAV_BAR_MODE_GESTURAL_OVERLAY = "com.android.internal.systemui.navbar.gestural";
-----------------------------------------------------------------------------------
根据手势加载不同的overlayPackage,也就是上面的三个包名
配置文件
这三个包都有对应的配置文件
config
这个文件配置了config_navBarInteractionMode,即该模式编号。
如下是3按钮导航的config.xml文件
<resources>
<!-- Controls the navigation bar interaction mode:
0: 3 button mode (back, home, overview buttons)
1: 2 button mode (back, home buttons + swipe up for overview)
2: gestures only for back, home and overview -->
<integer name="config_navBarInteractionMode">0</integer>
</resources>
strings
就是配置字符串,这个没什么好说的
dimens
这里配置了导航栏的宽高之类的,如下是手势导航的dimens.xml
<resources>
<!-- Height of the bottom navigation / system bar. -->
<dimen name="navigation_bar_height">16dp</dimen>
<!-- Height of the bottom navigation bar in portrait; often the same as @dimen/navigation_bar_height -->
<dimen name="navigation_bar_height_landscape">16dp</dimen>
<!-- Width of the navigation bar when it is placed vertically on the screen -->
<dimen name="navigation_bar_width">16dp</dimen>
<!-- Height of the bottom navigation / system bar. -->
<dimen name="navigation_bar_frame_height">48dp</dimen>
<!-- The height of the bottom navigation gesture area. -->
<dimen name="navigation_bar_gesture_height">32dp</dimen>
</resources>
当你选择了手势导航时,系统就会从这里获取资源。
如果你想配置三导航的宽高也可以在三导航的 overlayPackage 下添加dimens文件。
没有在对应的overlayPackage下添加dimens文件的话,系统默认会从frameworks/base/core/res/res/values/dimens.xml中获取,如下:
<!-- Height of the bottom navigation / system bar. -->
<dimen name="navigation_bar_height">48dp</dimen>
<!-- Height of the bottom navigation bar in portrait; often the same as @dimen/navigation_bar_height -->
<dimen name="navigation_bar_height_landscape">48dp</dimen>
<!-- Width of the navigation bar when it is placed vertically on the screen -->
<dimen name="navigation_bar_width">48dp</dimen>
<!-- Height of the bottom navigation bar frame; this is different than navigation_bar_height
where that is the height reported to all the other windows to resize themselves around the
navigation bar window but navigation_bar_frame_height is reported to SystemUI navigation
bar view's window -->
<dimen name="navigation_bar_frame_height">@dimen/navigation_bar_height</dimen>
<!-- Height of the bottom navigation bar frame in landscape -->
<dimen name="navigation_bar_frame_height_landscape">@dimen/navigation_bar_frame_height</dimen>
<!-- The height of the navigation gesture area if the gesture is starting from the bottom. -->
<dimen name="navigation_bar_gesture_height">@dimen/navigation_bar_frame_height</dimen>
BUG
前提:源码设置的默认导航模式其实是三按钮导航,我的代码设置的默认导航模式是手势导航
顺带一提,默认系统导航模式在frameworks/base/core/res/res/values/config.xml中设置,如下:
<!-- Controls the navigation bar interaction mode:
0: 3 button mode (back, home, overview buttons)
1: 2 button mode (back, home buttons + swipe up for overview)
2: gestures only for back, home and overview -->
<integer name="config_navBarInteractionMode">0</integer>
遇到过两个bug,一开始是设置大号字体且设置系统导航为三按钮导航后重启。
这个bug一开始我是将frameworks/base/core/res/res/values/dimens.xml的navigation_bar_height改回48dp(之前改为了16dp),设置大号字体且设置系统导航为三按钮导航后重启,问题完美解决,至少我是这么以为的。
然后恢复出厂设置第一次开机,默认是手势导航,然后高为48dp(应该为16dp的),导航栏空了一大块,整个人都不好了,然后又把frameworks/base/core/res/res/values/dimens.xml的值改回了16dp,检查了frameworks/base/packages/overlays/NavigationBarModeGesturalOverlay的配置,确实16dp,也没什么问题,但就是不起效,至今原因不明。
改动了很多值测试都没成功,没办法,又将代码恢复了最初的设置,将48dp改回了16dp,然后百度一下,大神还是很多的。
终于试了很多种方法后找出了一种有用的
大神原文:
【精选】Android 12默认手势导航及bug修复_ro.boot.vendor.overlay.theme_地球边的博客-CSDN博客
大神分析的原因我没看懂,但是方法确实有效。
搜索过程中遇到另一篇没看明白的文章,虽然没试过里面的方法,但也贴在这记录一下
记录修改系统默认导航模式_Only_Studio的博客-CSDN博客