以沉浸式模式显示 BottomSheetDialogFragment
Showing BottomSheetDialogFragment in immersive mode
我想在沉浸式模式下显示 BottomSheetDialogFragment。最初导航和状态栏会在显示对话框时显示,但我可以使用下面的代码对其进行排序。但是,当显示或关闭对话框时,导航栏会瞬间闪烁。有没有一种方法可以完全沉浸式地显示 BottomSheetDialogFragment,而导航栏不会在显示和关闭时闪烁?
abstract class ImmersiveBottomSheetDialogFragment<T : ViewDataBinding> : BottomSheetDialogFragment() {
protected lateinit var binding: T
private val systemUiVisibility: Int = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
fun showImmersive(
fragmentManager: FragmentManager,
tag: String,
tapOutsideEnabled: Boolean = false
) {
show(fragmentManager, tag)
fragmentManager.executePendingTransactions()
dialog?.let { dialog ->
dialog.setCanceledOnTouchOutside(tapOutsideEnabled)
dialog.window?.let { window ->
window.decorView.systemUiVisibility = systemUiVisibility
window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
}
}
}
}
添加这个:
override fun setupDialog(dialog: Dialog?, style: Int) {
super.setupDialog(dialog, style)
dialog?.window?.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
}
(from)
同时添加:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
var viewParent = view
while (viewParent is View) {
viewParent.fitsSystemWindows = false
viewParent.setOnApplyWindowInsetsListener { _, insets -> insets }
viewParent = viewParent.parent as View?
}
}
这是做什么的? DialogFragment#onActivityCreated()
调用 Dialog#setContentView()
,将对话框的视图包装在私有 'wrapInBottomSheet' 中。为了设置这些包装器视图的正确标志,我们想在包装后设置标志,例如在 super.onActivityCreated()
之后
另请观看 this talk 了解有关 fitsSystemWindows
和 window 插图的信息。
我想在沉浸式模式下显示 BottomSheetDialogFragment。最初导航和状态栏会在显示对话框时显示,但我可以使用下面的代码对其进行排序。但是,当显示或关闭对话框时,导航栏会瞬间闪烁。有没有一种方法可以完全沉浸式地显示 BottomSheetDialogFragment,而导航栏不会在显示和关闭时闪烁?
abstract class ImmersiveBottomSheetDialogFragment<T : ViewDataBinding> : BottomSheetDialogFragment() {
protected lateinit var binding: T
private val systemUiVisibility: Int = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
fun showImmersive(
fragmentManager: FragmentManager,
tag: String,
tapOutsideEnabled: Boolean = false
) {
show(fragmentManager, tag)
fragmentManager.executePendingTransactions()
dialog?.let { dialog ->
dialog.setCanceledOnTouchOutside(tapOutsideEnabled)
dialog.window?.let { window ->
window.decorView.systemUiVisibility = systemUiVisibility
window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
}
}
}
}
添加这个:
override fun setupDialog(dialog: Dialog?, style: Int) {
super.setupDialog(dialog, style)
dialog?.window?.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
}
(from)
同时添加:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
var viewParent = view
while (viewParent is View) {
viewParent.fitsSystemWindows = false
viewParent.setOnApplyWindowInsetsListener { _, insets -> insets }
viewParent = viewParent.parent as View?
}
}
这是做什么的? DialogFragment#onActivityCreated()
调用 Dialog#setContentView()
,将对话框的视图包装在私有 'wrapInBottomSheet' 中。为了设置这些包装器视图的正确标志,我们想在包装后设置标志,例如在 super.onActivityCreated()
另请观看 this talk 了解有关 fitsSystemWindows
和 window 插图的信息。