Jetpack Compose 主题样式实战:从基础到高级定制

在 Jetpack Compose 中,主题和样式是通过 MaterialTheme 和自定义样式系统实现的。下面我将通过实战示例展示如何自定义和应用主题样式。

1. 基础主题设置

定义颜色方案

// 自定义颜色方案
val MyAppColors = lightColors(
    primary = Color(0xFF6200EE),
    primaryVariant = Color(0xFF3700B3),
    secondary = Color(0xFF03DAC6),
    secondaryVariant = Color(0xFF018786),
    background = Color(0xFFFFFFFF),
    surface = Color(0xFFFFFFFF),
    error = Color(0xFFB00020),
    onPrimary = Color.White,
    onSecondary = Color.Black,
    onBackground = Color.Black,
    onSurface = Color.Black,
    onError = Color.White
)

// 深色主题颜色方案
val DarkColors = darkColors(
    primary = Color(0xFFBB86FC),
    primaryVariant = Color(0xFF3700B3),
    secondary = Color(0xFF03DAC6),
    background = Color(0xFF121212),
    surface = Color(0xFF1E1E1E),
    onPrimary = Color.Black,
    onBackground = Color.White,
    onSurface = Color.White
)

定义排版样式

val MyAppTypography = Typography(
    h1 = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Light,
        fontSize = 96.sp,
        letterSpacing = (-1.5).sp
    ),
    h2 = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Light,
        fontSize = 60.sp,
        letterSpacing = (-0.5).sp
    ),
    body1 = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = 16.sp,
        lineHeight = 24.sp,
        letterSpacing = 0.5.sp
    ),
    button = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Medium,
        fontSize = 14.sp,
        letterSpacing = 1.25.sp
    )
    // 可以继续定义其他文本样式...
)

定义形状样式

val MyAppShapes = Shapes(
    small = RoundedCornerShape(4.dp),
    medium = RoundedCornerShape(8.dp),
    large = RoundedCornerShape(16.dp)
)

应用主题

@Composable
fun MyAppTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    val colors = if (darkTheme) DarkColors else MyAppColors
    
    MaterialTheme(
        colors = colors,
        typography = MyAppTypography,
        shapes = MyAppShapes,
        content = content
    )
}

2. 实际应用示例

在应用中使用主题

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyAppTheme {
                // 整个应用的内容
                MyApp()
            }
        }
    }
}

@Composable
fun MyApp() {
    Surface(color = MaterialTheme.colors.background) {
        Column(modifier = Modifier.padding(16.dp)) {
            Text(
                text = "标题",
                style = MaterialTheme.typography.h1,
                color = MaterialTheme.colors.primary
            )
            Spacer(modifier = Modifier.height(16.dp))
            Button(onClick = { /* 点击操作 */ }) {
                Text("主题按钮")
            }
        }
    }
}

3. 高级样式技巧

创建自定义文本样式

@Composable
fun HighlightText(text: String) {
    Text(
        text = text,
        style = MaterialTheme.typography.body1.copy(
            background = MaterialTheme.colors.secondary.copy(alpha = 0.2f),
            fontWeight = FontWeight.Bold
        ),
        modifier = Modifier.padding(4.dp)
    )
}

自定义按钮样式

@Composable
fun PrimaryButton(
    text: String,
    onClick: () -> Unit,
    modifier: Modifier = Modifier
) {
    Button(
        onClick = onClick,
        colors = ButtonDefaults.buttonColors(
            backgroundColor = MaterialTheme.colors.primary,
            contentColor = MaterialTheme.colors.onPrimary
        ),
        shape = MaterialTheme.shapes.medium,
        elevation = ButtonDefaults.elevation(
            defaultElevation = 8.dp,
            pressedElevation = 4.dp
        ),
        modifier = modifier
    ) {
        Text(text, style = MaterialTheme.typography.button)
    }
}

动态主题切换

@Composable
fun ThemeSwitcherExample() {
    var isDarkTheme by remember { mutableStateOf(false) }
    
    MyAppTheme(darkTheme = isDarkTheme) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Switch(
                checked = isDarkTheme,
                onCheckedChange = { isDarkTheme = it },
                colors = SwitchDefaults.colors(
                    checkedThumbColor = MaterialTheme.colors.secondary,
                    uncheckedThumbColor = MaterialTheme.colors.primary
                )
            )
            Text(
                text = if (isDarkTheme) "深色主题" else "浅色主题",
                style = MaterialTheme.typography.h6
            )
            Spacer(modifier = Modifier.height(16.dp))
            PrimaryButton(text = "示例按钮", onClick = {})
        }
    }
}

4. 主题扩展实践

创建扩展属性

// 定义扩展属性
val Colors.success: Color
    get() = Color(0xFF4CAF50)

val Colors.warning: Color
    get() = Color(0xFFFFC107)

val Colors.info: Color
    get() = Color(0xFF2196F3)

// 使用扩展属性
@Composable
fun StatusIndicator(status: String) {
    val color = when(status) {
        "success" -> MaterialTheme.colors.success
        "warning" -> MaterialTheme.colors.warning
        "error" -> MaterialTheme.colors.error
        else -> MaterialTheme.colors.info
    }
    
    Box(
        modifier = Modifier
            .size(16.dp)
            .background(color, CircleShape)
    )
}

创建自定义主题组件

@Composable
fun Card(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {
    Surface(
        modifier = modifier,
        shape = MaterialTheme.shapes.medium,
        elevation = 4.dp,
        color = MaterialTheme.colors.surface,
        content = content
    )
}

// 使用示例
@Composable
fun UserProfileCard(user: User) {
    Card(modifier = Modifier.padding(8.dp)) {
        Column(modifier = Modifier.padding(16.dp)) {
            Text(
                text = user.name,
                style = MaterialTheme.typography.h6,
                color = MaterialTheme.colors.onSurface
            )
            Spacer(modifier = Modifier.height(8.dp))
            Text(
                text = user.bio,
                style = MaterialTheme.typography.body2
            )
        }
    }
}

5. 响应式主题设计

@Composable
fun ResponsiveContent() {
    // 根据屏幕宽度决定布局
    val configuration = LocalConfiguration.current
    val screenWidth = configuration.screenWidthDp.dp
    
    val isWideScreen = screenWidth >= 600.dp
    
    if (isWideScreen) {
        Row {
            // 宽屏布局
            NavigationRail()
            MainContent()
        }
    } else {
        // 窄屏布局
        Scaffold(
            bottomBar = { BottomNavigation() }
        ) {
            MainContent()
        }
    }
}

@Composable
fun NavigationRail() {
    NavigationRail(
        backgroundColor = MaterialTheme.colors.surface,
        contentColor = MaterialTheme.colors.onSurface
    ) {
        // 导航项...
    }
}

通过以上实战示例,你可以全面掌握 Jetpack Compose 中的主题和样式应用。记住,Compose 的声明式特性使得样式重用和主题切换变得非常简单,合理组织你的主题系统可以大大提高 UI 的一致性和开发效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值