繁体   English   中英

如何使用可组合物在应用程序中动态切换明暗主题

[英]How to switch between light and dark theme dynamically in app using composables

您如何通过在应用程序内按下按钮在主题的调色板之间动态切换

这就是我目前所做的,但只有当我将 Android 主题切换到深色或浅色模式时才有效

应用主题.Kt

@Model
object ThemeState {
    var isLight: Boolean = true
}


@Composable
fun MyAppTheme(
    children: @Composable() () -> Unit
) {
    MaterialTheme(colors = if (ThemeState.isLight) themeColorsLight else themColorDark) {
            children()
    }
}

MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyAppTheme(children = {
                Surface {
                    Greetings(name = "Android")
                }

            })

        }
    }
}

@Composable
fun Greetings(name: String) {

    Column(modifier = Modifier.fillMaxHeight()) {
        Column(modifier = Modifier.weight(1f)) {
            Text(
                text = "Hello $name", modifier = Modifier.padding(24.dp),
                style = MaterialTheme.typography.h1
            )
        }

        Button(onClick = { ThemeState.isLight = !ThemeState.isLight }) {
            Text(text = "Change Theme IsLight:${ThemeState.isLight}")
        }
    }
}

目前我不知道为什么你的代码不起作用,当我发现时我会更新这个答案。

但不要将if else用于colors参数,而是将其用于整个 MaterialTheme,就像这样,它将起作用:

@Composable
fun MyAppTheme(
    children: @Composable() () -> Unit
) {

    if (ThemeState.isLight) {
        MaterialTheme(colors = themeColorsLight) {
            children()
        }
    } else {
        MaterialTheme(colors = themColorDark) {
            children()
        }

    }
}

更新:似乎它是 Jetpack Compose dev11 中的错误,我在 dev12 中尝试过,它在那里工作。

注意 1: @Model在开发 12 中已被弃用,将您的ThemeState更改为

object ThemeState {
    var isLight by mutableStateOf(true)
}

更多信息: https://android-review.googlesource.com/c/platform/frameworks/support/+/1311293

注意 2在 AndroidStudio 的最新版本中自动导入存在一些问题如果 Idea 抛出错误: Type 'MutableState<TypeVariable(T)>' has no method 'getValue(ThemeState, KProperty<*>)' and thus it cannot serve as a delegate

手动导入getValueSetValue

import androidx.compose.getValue
import androidx.compose.setValue

从 0.1.0-dev16 开始使用这些导入:

import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue

使用AppCompatDelegate class

第 1 步:定义一个 state,它最初将指向 Light 模式。

object ThemeState {
 var darkModeState : MutableState<Boolean> = mutableStateOf(false)
}

注意:每当这个 state 发生变化时,所有读取这个 state 值的方法也会被调用。

第 2 步:定义用于读取 state 的变量

val isDark = ThemeState.darkModeState.value

第 3 步:现在将主题模式从暗更改为亮,反之亦然,如下所示

Button(onClick = {

            val theme = when(isDark){
                true -> AppCompatDelegate.MODE_NIGHT_NO
                false -> AppCompatDelegate.MODE_NIGHT_YES
            }
            AppCompatDelegate.setDefaultNightMode(theme)
            ThemeState.darkModeState.value = !isDark

        }) {
            Text(text = "Theme Toggle Button")
        }

正如您在此处看到的,每次单击主题切换按钮时,我都会更改应用程序主题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM