美文网首页
Compose利用State显示弹窗不会引起状态栏更改的一种方案

Compose利用State显示弹窗不会引起状态栏更改的一种方案

作者: 伪装的狼 | 来源:发表于2023-05-25 11:10 被阅读0次

前言

因为业务需求需要做全屏展示,比较理想的效果就是布局延伸到状态栏底部,并且隐藏底部导航栏。

为什么不直接用自带的弹窗Dialog?

用自带的弹窗Dialog弹出显示的时候会把状态栏和底部导航栏顶出来,这个时候需要在onWindowFocusChanged进行隐藏,就会有显示又隐藏的动画,显得不是很美观。

实现原理

其实是利用了Compose渲染机制,修改state之后会进行重组,并且界面可以叠加渲染的原理,渲染在前面的界面在底部,后渲染的在顶部。那么后渲染的界面加上半透明灰色背景,布局中间编写弹窗界面即可实现与自带Dialog一致的弹窗效果。由于是在decorView上面绘制的,不会引起状态栏变化。

怎么实现?

编写State类

sealed class UiState {
    object Main: UiState()
    object Loading: UiState()
    data class Success(val text: Text): UiState()
    object Error: UiState()
}

在ViewModel添加StateFlow,使用热流Flow来收集状态数据

private val _uiState = MutableStateFlow<UiState>(UiState.Main)
val uiState: StateFlow<UiState> = _uiState

fun setState(state: UiState) {
        _uiState.value = state
    }

在Compose组件内收集Flow数据流:

MainContainer() // 主页布局Compose

// 根据state叠加显示弹窗,需要放在主页布局后面
when (viewModel.uiState.collectAsState().value) {
    is UiState.Success -> {
        showSuccessDialog()
    }
    is UiState.Loading -> {
        showLoadingDialog()
    }
    is UiState.Error -> {
        showErrorDialog()
    }
    else -> {
        
    }
}

通过控制状态来展示不同的弹窗

viewModel.setState(UiState.Success)

实现沉浸式全屏

onCreate添加以下代码:

window.apply {
    WindowCompat.setDecorFitsSystemWindows(this, false)
    setFlags(
        WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
        WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
    )
    decorView.systemUiVisibility =
        (View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)
}

View系可以吗?

decorView.addView()也可以实现类似效果,不过需要自行控制view的显示和隐藏。自定义弹窗View,然后addView上去即可。

val view = View(this@FullDialogActivity)
view.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
view.background = ContextCompat.getDrawable(this@FullDialogActivity, R.color.purple_200)
(decorView as ViewGroup).addView(view)

相关文章

网友评论

      本文标题:Compose利用State显示弹窗不会引起状态栏更改的一种方案

      本文链接:https://www.haomeiwen.com/subject/fqlhedtx.html