项目中有个需求,需要根据虚拟导航栏的显示、隐藏状态,动态修改页面中控件的高度来适配,尝试过网上很多计算页面显示高度来动态检测NavigationBar显示隐藏的方法,基本都不太好使,后来发现以下方案比较好用:
UIExt.kt
/**
* 虚拟导航栏显示、隐藏监听
* 该方法只有在导航栏发生变化时才会触发
*/
@SuppressLint("ObsoleteSdkInt")
fun isNavigationBarChanged(
activity: Activity,
onNavigationStateListener: OnNavigationStateListener?
) {
val height: Int = getNavigationBarHeight(activity)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
ViewCompat.setOnApplyWindowInsetsListener(activity.window.decorView) { v, insets ->
var isShowing = false
var b = 0
if (insets != null) {
b = insets.systemWindowInsetBottom
isShowing = b == height
}
if (onNavigationStateListener != null && b <= height) {
onNavigationStateListener.onNavigationState(isShowing, b)
}
ViewCompat.onApplyWindowInsets(v,insets)
}
}
}
interface OnNavigationStateListener {
fun onNavigationState(isShowing: Boolean, b: Int)
}
/**
* 获取虚拟导航栏高度 方法1
*/
fun getNavigationBarHeight(context: Context): Int {
val resources = context.resources
val resourceId: Int = resources.getIdentifier("navigation_bar_height", "dimen", "android")
return resources.getDimensionPixelSize(resourceId)
}
使用:
因为要动态监听,比如在应用中切到系统设置去开关了虚拟导航栏再回到应用里,所以写在onWindowFocusChanged回调中比较合适。
MainActivity.kt
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
isNavigationBarChanged(this, object : OnNavigationStateListener {
override fun onNavigationState(isShowing: Boolean, b: Int) {
LogUtils.logE("isNavigationBarExist---${isShowing}")
//todo 根据showing的值去写自己的逻辑
}
})
}
网友评论