我们在设备使用虚拟键导航时,弹窗弹出会调起底部导航栏导致抖动一下,原因是因为Dialog获取到了焦点导致导航栏被唤起
基于Kotlin的扩展方法,这里写一个工具类
/**
* 初始化底部导航栏防抖动配置
*/
fun DialogFragment.initHideNavigationBarConfig() {
// 防止虚拟导航抖动
dialog?.apply {
window?.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
setOnShowListener {
window?.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
hideNavigationBar(this)
}
}
}
/**
* 初始化底部导航栏防抖动配置
*/
fun Dialog.initHideNavigationBarConfig() {
// 防止虚拟导航抖动
window?.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
setOnShowListener {
window?.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
hideNavigationBar(this)
}
}
/**
* 透明显示tab栏
*/
private fun hideNavigationBar(dialog: Dialog) {
dialog.window.let {
val decorView = it.decorView
val uiOptions =
(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
decorView.systemUiVisibility = uiOptions
}
}
使用方法是在Dialog或者FragmentDialog的onCreate方法中直接调用initHideNavigationBarConfig()即可
原理为弹窗设置不可获取焦点,在弹窗弹出后去除不可获取焦点标签,使弹出可以点击额外区域取消,且不会发生点击穿透,然后兼容部分机型,在弹出后调用hideNavigationBar隐藏状态栏