和你一起终身学习,这里是程序员Android
经典好文推荐,通过阅读本文,您将收获以下知识点:
一、前言
二、导航栏的处理
三、 修改StatusHostLayout方案
四、总结
一、前言
在之前的文章中,大家比较关注宿主侵入的方式,并且有要求适配导航栏的操作。
其实大部分的应用都只需要使用到状态栏,导航栏由系统去管理,为什么不自己管理导航栏,就是导航栏的坑太多。
背景设置的坑,判断是否存在的坑,手动设置隐藏显示导航栏的坑,导航栏高度获取的坑。
如果项目中确实需要用到操作导航栏怎么办?
二、导航栏的处理
导航栏为什么难处理,因为之前的一些添加Flag的方案有些不实用,有兼容问题,也可以说手机厂商并没有完全适配,导致兼容性有问题。
而我们通过 WindowInsetsController / WindowInsets 的一些方式则可以相对方便的操作导航栏。
那么是不是 WindowInsetsController / WindowInsets 的方式就完全兼容了呢?也并不是,只是相对好一点,重要的功能能用而已。
下面介绍一下相对稳定的一些操作方法。
2.1 判断当前是否显示了导航栏
/**
* 当前是否显示了底部导航栏
*/
public static void hasNavigationBars(Activity activity, BooleanValueCallback callback) {
View decorView = activity.findViewById(android.R.id.content);
boolean attachedToWindow = decorView.isAttachedToWindow();
if (attachedToWindow) {
WindowInsetsCompat windowInsets = ViewCompat.getRootWindowInsets(decorView);
if (windowInsets != null) {
boolean hasNavigationBar = windowInsets.isVisible(WindowInsetsCompat.Type.navigationBars()) &&
windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom > 0;
callback.onBoolean(hasNavigationBar);
}
} else {
decorView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
WindowInsetsCompat windowInsets = ViewCompat.getRootWindowInsets(v);
if (windowInsets != null) {
boolean hasNavigationBar = windowInsets.isVisible(WindowInsetsCompat.Type.navigationBars()) &&
windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom > 0;
callback.onBoolean(hasNavigationBar);
}
}
@Override
public void onViewDetachedFromWindow(View v) {
}
});
}
}
复制代码
其实核心代码是一样的,只是区分了是否已经onAttach了,防止在onCreate方法中调用的时候会报错。
它的核心思路是和老版本的方法是相似的,只是老版本是从window中找到导航栏布局去判断是否隐藏和显示和判断高度。而新版本通过WindowInset 的方式获取导航栏对象相对比较稳妥。
2.2 获取导航栏的高度
/**
* 获取底部导航栏的高度
*/
public static void getNavigationBarHeight(View view, HeightValueCallback callback) {
boolean attachedToWindow = view.isAttachedToWindow();
if (attachedToW