是否有 Jetpack Compose 相当于 android:keepScreenOn 来保持屏幕处于活动状态?

Bha*_*har 25 android android-jetpack-compose

我有一个可组合项,它使用处理程序来缓慢更新可组合项内图像的 Alpha。但是,我发现屏幕在动画完成之前关闭。

在 XML 布局中,我们可以使用
android:keepScreenOn
或使其保持活动状态
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

有没有办法使用 compose 来执行此操作而不使用唤醒锁权限?

Phi*_*hov 34

您可以使用它LocalContext来获取活动,并且它有一个窗口,您可以在其中应用所需的标志。

在这种情况下,当您需要在视图出现和消失上运行一些代码时,DisposableEffect可以使用:

@Composable
fun KeepScreenOn() {
    val context = LocalContext.current
    DisposableEffect(Unit) {
        val window = context.findActivity()?.window
        window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        onDispose {
            window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        }
    }
}

fun Context.findActivity(): Activity? {
    var context = this
    while (context is ContextWrapper) {
        if (context is Activity) return context
        context = context.baseContext
    }
    return null
}
Run Code Online (Sandbox Code Playgroud)

用法:当屏幕出现时,标志设置为打开,当屏幕消失时,标志被清除。

@Composable
fun Screen() {
    KeepScreenOn()
}
Run Code Online (Sandbox Code Playgroud)

正如 @Louis CAD 正确指出的那样,如果您在许多视图中使用此“视图”,则可能会遇到问题:如果出现一个使用它的视图,然后消失也使用它的先前视图,它将重置该标志。

我还没有找到一种跟踪flags状态来更新视图的方法,我认为 @Louis CAD解决方案是可以的,直到 Compose 有一些系统支持。

  • 如果您在合成中使用了多个“KeepScreenOn()”,则可能会导致干扰,并且该标志可能会在不应该被删除的情况下被删除。 (6认同)

Fir*_*enk 22

以更 Compose 的方式:

@Composable
fun KeepScreenOn() {
    val currentView = LocalView.current
    DisposableEffect(Unit) {
        currentView.keepScreenOn = true
        onDispose {
            currentView.keepScreenOn = false
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

一旦视图从合成中消失,这将被处理。用法很简单:

@Composable
fun Screen() {
    KeepScreenOn()
}
Run Code Online (Sandbox Code Playgroud)


Lou*_*CAD 18

如果您在同一组合物中有多种用途,那么这一点应该不会受到任何干扰:

@Composable
fun KeepScreenOn() = AndroidView({ View(it).apply { keepScreenOn = true } })
Run Code Online (Sandbox Code Playgroud)

用法就这么简单:

if (screenShallBeKeptOn) {
    KeepScreenOn()
}
Run Code Online (Sandbox Code Playgroud)