虚拟导航(NavigationBar)栏适配

简介: 做过屏幕适配的同学都知道Android的NavigationBar适配是个问题,尤其是那些NavigationBar还可以动态隐藏显示的,那就更蛋疼了。

虚拟导航(NavigationBar)栏适配

做过屏幕适配的同学都知道Android的NavigationBar适配是个问题,尤其是那些NavigationBar还可以动态隐藏显示的,那就更蛋疼了。

比如下面:

NavigationBar的显示与隐藏,会直接改变屏幕的可用高度。

如果我们的操作是跟动态获取的屏幕高度相关的,那就悲剧了,如果不做特殊处理,是不会主动响应屏幕高度变化的。

NavigationBar显示的实例

我们来看个实例,先看下显示NavigationBar时手机的高度:

代码如下:
在Activity#onCreate方法里面添加如下代码:

LogUtils.e(TAG, "ScreenWidth:" + ScreenUtils.getScreenW(this));
LogUtils.e(TAG, "ScreenHeight:" + ScreenUtils.getScreenH(this));

工具类如下:

/**
 * 获取屏幕宽度
 */
public static int getScreenW(Context context) {
    DisplayMetrics dm = context.getResources().getDisplayMetrics();
    int w = dm.widthPixels;
    return w;
}

/**
 * 获取屏幕高度
 */
public static int getScreenH(Context context) {
    DisplayMetrics dm = context.getResources().getDisplayMetrics();
    int h = dm.heightPixels;
    return h;
}

具体操作如下:

输出log如下:

E: ScreenWidth:1080
E: ScreenHeight:1792

NavigationBar隐藏的实例

再看下隐藏NavigationBar时手机的高度:
代码不变,具体操作如下:

输出log如下:

E: ScreenWidth:1080
E: ScreenHeight:1920

可以看出NavigationBar隐藏与显示时获取到的屏幕高度是不同的。NavigationBar隐藏时屏幕高度为1920px,NavigationBar显示时屏幕高度为1792px。

NavigationBar动态显示和隐藏

下面我们看个例子,模拟用户在当前Avtivity内部隐藏、显示导航栏操作。我们通过给根View注册ViewTreeObserver.OnGlobalLayoutListener监听器来监听NavigationBar的隐藏于显示。代码如下:

globalLayoutListener = () -> {
    LogUtils.e(TAG, "ScreenWidth111:" + ScreenUtils.getScreenW(AdaptiveNavigationBarActivity.this));
    LogUtils.e(TAG, "ScreenHeight111:" + ScreenUtils.getScreenH(AdaptiveNavigationBarActivity.this));
};
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(globalLayoutListener);

我们进行如下操作:

可以看到输出如下:

NavigationBar从显示到隐藏:

E: ScreenWidth111:1080
E: ScreenHeight111:1920

NavigationBar从隐藏到显示:

E: ScreenWidth111:1080
E: ScreenHeight111:1920

可以看出,在NavigationBar的隐藏显示状态变更时,我们通过常规方式获取到的屏幕高度是不变的。

我们如何才能获取到真实的可用屏幕高度呢?

我们在监听器中添加如下代码:

Rect r = new Rect();
//获取当前界面可视部分,如果NavigationBar可用,就包含其高度。
getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
int realHeight = r.bottom;
LogUtils.e(TAG, "realHeight:" + realHeight);

然后我们再做NavigationBar隐藏显示的操作,可以看到如下log:

NavigationBar从显示到隐藏:

E: ScreenWidth111:1080
E: ScreenHeight111:1920
E: realHeight:1920

NavigationBar从隐藏到显示:

E: ScreenWidth111:1080
E: ScreenHeight111:1920
E: realHeight:1792

此时获取到的高度r.bottom就是真实的可见高度。

如果我们遇到类似的需求时,用这种方式进行适配即可。

相关文章
|
6月前
flutter 导航组件 AppBar (含顶部选项卡TabBar,抽屉菜单 drawer ,自定义导航图标)
flutter 导航组件 AppBar (含顶部选项卡TabBar,抽屉菜单 drawer ,自定义导航图标)
109 1
|
6月前
|
小程序 API
【微信小程序-原生开发】实用教程07 - Grid 宫格导航,详情页,侧边导航(含自定义页面顶部导航文字)
【微信小程序-原生开发】实用教程07 - Grid 宫格导航,详情页,侧边导航(含自定义页面顶部导航文字)
126 0
|
iOS开发
iOS 15后设置导航控制器的导航条背景色无效的问题处理
iOS 15后设置导航控制器的导航条背景色无效的问题处理
508 0
|
Android开发
Android 11 SystemUI(状态/导航栏)-状态栏下拉时图标的隐藏与通知面板的半透黑色背景
Android 11 SystemUI(状态/导航栏)-状态栏下拉时图标的隐藏与通知面板的半透黑色背景
897 0
Android 11 SystemUI(状态/导航栏)-状态栏下拉时图标的隐藏与通知面板的半透黑色背景
|
iOS开发
IOS15上纯代码布局之导航控制器的导航条为透明的问题
IOS15上纯代码布局之导航控制器的导航条为透明的问题
234 0
|
架构师 开发者
导航控件|学习笔记
快速学习导航控件。
107 0
导航控件|学习笔记
html+css实战190-侧导航布局-箭头
html+css实战190-侧导航布局-箭头
167 0
html+css实战190-侧导航布局-箭头
|
开发者
导航控件| 学习笔记
快速学习导航控件。
|
Android开发
Fragment实现微信Tab界面(不可通过界面左右拖动切换界面,只可以由按钮切换)
Fragment实现微信Tab界面(不可通过界面左右拖动切换界面,只可以由按钮切换)
3195 0
半透明菜单导航
在线演示 本地下载
821 0