如何使用可组合在应用程序中动态切换浅色和深色主题

Bro*_*own 7 android android-theme kotlin android-jetpack-compose

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

这是我到目前为止所做的,但仅在我将 Android 主题切换到暗模式或亮模式时才有效

应用主题.Kt

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


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

主活动.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}")
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

Hab*_*emi 10

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

但不是使用if elseforcolors参数,而是像这样将它用于整个 MaterialTheme,它会起作用:

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

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

    }
}
Run Code Online (Sandbox Code Playgroud)

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

注意 1: @Model在 dev 12 中已弃用,将您的更改ThemeState

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

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

    }
}
Run Code Online (Sandbox Code Playgroud)

更多信息: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手动。

object ThemeState {
    var isLight by mutableStateOf(true)
}
Run Code Online (Sandbox Code Playgroud)

由于 0.1.0-dev16 使用这些导入:

import androidx.compose.getValue
import androidx.compose.setValue
Run Code Online (Sandbox Code Playgroud)