一、@Preview 注解
- 使用
@Preview注解实现预览,该注解有多个参数
kotlin
annotation class Preview(
val name: String = "",
val group: String = "",
@IntRange(from = 1) val apiLevel: Int = -1,
// TODO(mount): Make this Dp when they are inline classes
val widthDp: Int = -1,
// TODO(mount): Make this Dp when they are inline classes
val heightDp: Int = -1,
val locale: String = "",
@FloatRange(from = 0.01) val fontScale: Float = 1f,
val showSystemUi: Boolean = false,
val showBackground: Boolean = false,
val backgroundColor: Long = 0,
@UiMode val uiMode: Int = 0,
@Device val device: String = Devices.DEFAULT,
@Wallpaper val wallpaper: Int = Wallpapers.NONE,
)
-
Android Studio 预览窗口的右上角的
Build & Refresh按钮 -
可以同时拥有多个预览
kotlin
@Preview(showBackground = true, name = "Compact Preview")
@Preview(showBackground = true, name = "Medium Preview", widthDp = 700)
@Preview(showBackground = true, name = "Expanded Preview", widthDp = 1000)
二、@Preview 注解参数
- name:预览名称
kotlin
@Preview(name = "登录按钮预览")
@Composable
fun LoginButtonPreview() {
Button(onClick = {}) { Text("登录") }
}
- group:分组
kotlin
@Preview(group = "按钮组")
@Composable
fun PrimaryButtonPreview() {
Button(onClick = {}) { Text("主要按钮") }
}
@Preview(group = "按钮组")
@Composable
fun SecondaryButtonPreview() {
Button(onClick = {}) { Text("次要按钮") }
}
-
widthDp:固定宽度
-
heightDp:固定高度
kotlin
@Preview(widthDp = 200, heightDp = 100)
@Composable
fun FixedSizePreview() {
Box(Modifier.background(Color.Blue)) {
Text("宽 200 dp,高 100 dp", color = Color.White)
}
}
-
showBackground:显示背景
-
backgroundColor:背景颜色
kotlin
@Preview(showBackground = true)
@Composable
fun WithBackgroundPreview() {
Text("背景可见", color = Color.White)
}
@Preview(
showBackground = true,
backgroundColor = 0xFF2196F3
)
@Composable
fun CustomBgPreview() {
Text("蓝色背景上的文字", color = Color.White)
}
- uiMode:深色 / 浅色模式
kotlin
package com.example.reply.ui.theme
import androidx.compose.ui.graphics.Color
val md_theme_light_primary = Color(0xFF006879)
val md_theme_light_onPrimary = Color(0xFFFFFFFF)
val md_theme_light_primaryContainer = Color(0xFFA9EDFF)
val md_theme_light_onPrimaryContainer = Color(0xFF001F26)
val md_theme_light_secondary = Color(0xFF4B6268)
val md_theme_light_onSecondary = Color(0xFFFFFFFF)
val md_theme_light_secondaryContainer = Color(0xFFCEE7EE)
val md_theme_light_onSecondaryContainer = Color(0xFF061F24)
val md_theme_light_tertiary = Color(0xFF565D7E)
val md_theme_light_onTertiary = Color(0xFFFFFFFF)
val md_theme_light_tertiaryContainer = Color(0xFFDDE1FF)
val md_theme_light_onTertiaryContainer = Color(0xFF121A37)
val md_theme_light_error = Color(0xFFBA1A1A)
val md_theme_light_errorContainer = Color(0xFFFFDAD6)
val md_theme_light_onError = Color(0xFFFFFFFF)
val md_theme_light_onErrorContainer = Color(0xFF410002)
val md_theme_light_background = Color(0xFFFBFCFD)
val md_theme_light_onBackground = Color(0xFF191C1D)
val md_theme_light_surface = Color(0xFFFBFCFD)
val md_theme_light_onSurface = Color(0xFF191C1D)
val md_theme_light_surfaceVariant = Color(0xFFDBE4E7)
val md_theme_light_onSurfaceVariant = Color(0xFF3F484B)
val md_theme_light_outline = Color(0xFF6F797B)
val md_theme_light_inverseOnSurface = Color(0xFFEFF1F2)
val md_theme_light_inverseSurface = Color(0xFF2E3132)
val md_theme_light_inversePrimary = Color(0xFF54D7F3)
val md_theme_light_surfaceTint = Color(0xFF006879)
val md_theme_light_outlineVariant = Color(0xFFBFC8CB)
val md_theme_light_scrim = Color(0xFF000000)
val md_theme_dark_primary = Color(0xFF54D7F3)
val md_theme_dark_onPrimary = Color(0xFF003640)
val md_theme_dark_primaryContainer = Color(0xFF004E5B)
val md_theme_dark_onPrimaryContainer = Color(0xFFA9EDFF)
val md_theme_dark_secondary = Color(0xFFB2CBD2)
val md_theme_dark_onSecondary = Color(0xFF1C343A)
val md_theme_dark_secondaryContainer = Color(0xFF334A50)
val md_theme_dark_onSecondaryContainer = Color(0xFFCEE7EE)
val md_theme_dark_tertiary = Color(0xFFBEC5EB)
val md_theme_dark_onTertiary = Color(0xFF282F4D)
val md_theme_dark_tertiaryContainer = Color(0xFF3E4565)
val md_theme_dark_onTertiaryContainer = Color(0xFFDDE1FF)
val md_theme_dark_error = Color(0xFFFFB4AB)
val md_theme_dark_errorContainer = Color(0xFF93000A)
val md_theme_dark_onError = Color(0xFF690005)
val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
val md_theme_dark_background = Color(0xFF191C1D)
val md_theme_dark_onBackground = Color(0xFFE1E3E4)
val md_theme_dark_surface = Color(0xFF191C1D)
val md_theme_dark_onSurface = Color(0xFFE1E3E4)
val md_theme_dark_surfaceVariant = Color(0xFF3F484B)
val md_theme_dark_onSurfaceVariant = Color(0xFFBFC8CB)
val md_theme_dark_outline = Color(0xFF899295)
val md_theme_dark_inverseOnSurface = Color(0xFF191C1D)
val md_theme_dark_inverseSurface = Color(0xFFE1E3E4)
val md_theme_dark_inversePrimary = Color(0xFF006879)
val md_theme_dark_surfaceTint = Color(0xFF54D7F3)
val md_theme_dark_outlineVariant = Color(0xFF3F484B)
val md_theme_dark_scrim = Color(0xFF000000)
kotlin
package com.example.reply.ui.theme
import android.app.Activity
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.core.view.WindowCompat
private val LightColorScheme = lightColorScheme(
primary = md_theme_light_primary,
onPrimary = md_theme_light_onPrimary,
primaryContainer = md_theme_light_primaryContainer,
onPrimaryContainer = md_theme_light_onPrimaryContainer,
secondary = md_theme_light_secondary,
onSecondary = md_theme_light_onSecondary,
secondaryContainer = md_theme_light_secondaryContainer,
onSecondaryContainer = md_theme_light_onSecondaryContainer,
tertiary = md_theme_light_tertiary,
onTertiary = md_theme_light_onTertiary,
tertiaryContainer = md_theme_light_tertiaryContainer,
onTertiaryContainer = md_theme_light_onTertiaryContainer,
error = md_theme_light_error,
errorContainer = md_theme_light_errorContainer,
onError = md_theme_light_onError,
onErrorContainer = md_theme_light_onErrorContainer,
background = md_theme_light_background,
onBackground = md_theme_light_onBackground,
surface = md_theme_light_surface,
onSurface = md_theme_light_onSurface,
surfaceVariant = md_theme_light_surfaceVariant,
onSurfaceVariant = md_theme_light_onSurfaceVariant,
outline = md_theme_light_outline,
inverseOnSurface = md_theme_light_inverseOnSurface,
inverseSurface = md_theme_light_inverseSurface,
inversePrimary = md_theme_light_inversePrimary,
surfaceTint = md_theme_light_surfaceTint,
outlineVariant = md_theme_light_outlineVariant,
scrim = md_theme_light_scrim,
)
private val DarkColorScheme = darkColorScheme(
primary = md_theme_dark_primary,
onPrimary = md_theme_dark_onPrimary,
primaryContainer = md_theme_dark_primaryContainer,
onPrimaryContainer = md_theme_dark_onPrimaryContainer,
secondary = md_theme_dark_secondary,
onSecondary = md_theme_dark_onSecondary,
secondaryContainer = md_theme_dark_secondaryContainer,
onSecondaryContainer = md_theme_dark_onSecondaryContainer,
tertiary = md_theme_dark_tertiary,
onTertiary = md_theme_dark_onTertiary,
tertiaryContainer = md_theme_dark_tertiaryContainer,
onTertiaryContainer = md_theme_dark_onTertiaryContainer,
error = md_theme_dark_error,
errorContainer = md_theme_dark_errorContainer,
onError = md_theme_dark_onError,
onErrorContainer = md_theme_dark_onErrorContainer,
background = md_theme_dark_background,
onBackground = md_theme_dark_onBackground,
surface = md_theme_dark_surface,
onSurface = md_theme_dark_onSurface,
surfaceVariant = md_theme_dark_surfaceVariant,
onSurfaceVariant = md_theme_dark_onSurfaceVariant,
outline = md_theme_dark_outline,
inverseOnSurface = md_theme_dark_inverseOnSurface,
inverseSurface = md_theme_dark_inverseSurface,
inversePrimary = md_theme_dark_inversePrimary,
surfaceTint = md_theme_dark_surfaceTint,
outlineVariant = md_theme_dark_outlineVariant,
scrim = md_theme_dark_scrim,
)
@Composable
fun ReplyTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = false,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) {
dynamicDarkColorScheme(context)
} else {
dynamicLightColorScheme(context)
}
}
darkTheme -> DarkColorScheme
else -> LightColorScheme
}
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
val window = (view.context as Activity).window
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
}
}
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content
)
}
kotlin
@Composable
fun Greeting(name: String) {
Box(modifier = Modifier.fillMaxSize()) {
Text(
text = "Hello, $name!",
color = MaterialTheme.colorScheme.primary
)
}
}
@Preview(name = "Light Mode", uiMode = Configuration.UI_MODE_NIGHT_NO)
@Composable
fun PreviewGreetingLight() {
ReplyTheme {
Greeting("World")
}
}
@Preview(name = "Dark Mode", uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun PreviewGreetingDark() {
ReplyTheme {
Greeting("World")
}
}
- fontScale:字体缩放
kotlin
@Preview(fontScale = 1.0f)
@Composable
fun FontScalePreview1() {
Text("some text")
}
@Preview(fontScale = 2.0f)
@Composable
fun FontScalePreview2() {
Text("some text")
}
- showSystemUi:显示系统栏
kotlin
@Preview(showSystemUi = true)
@Composable
fun WithSystemUIPreview() {
Column(modifier = Modifier.fillMaxSize()) {
Text("顶部有状态栏,底部有导航栏")
}
}