Compose 常用组件总结和高级组件与优化技巧

发布于:2025-04-05 ⋅ 阅读:(38) ⋅ 点赞:(0)

Compose 常用组件总结

基础布局组件

  1. Box - 类似传统View系统中的FrameLayout

    Box(modifier = Modifier.fillMaxSize()) {
        Text("在Box底部", modifier = Modifier.align(Alignment.BottomCenter))
    }
    
  2. Column - 垂直排列子项

    Column(
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("第一项")
        Text("第二项")
    }
    
  3. Row - 水平排列子项

    Row(
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Text("左边")
        Text("右边")
    }
    

文本组件

  1. Text - 显示文本

    Text(
        text = "Hello Compose",
        color = Color.Blue,
        fontSize = 20.sp,
        fontWeight = FontWeight.Bold,
        modifier = Modifier.padding(8.dp)
    )
    
  2. BasicTextField - 基本文本输入

    var text by remember { mutableStateOf("") }
    BasicTextField(
        value = text,
        onValueChange = { text = it }
    )
    
  3. TextField - 带样式的文本输入

    var text by remember { mutableStateOf("") }
    TextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("用户名") },
        placeholder = { Text("请输入用户名") }
    )
    

按钮组件

  1. Button - 基本按钮

    Button(
        onClick = { /* 点击事件 */ },
        enabled = true,
        colors = ButtonDefaults.buttonColors(backgroundColor = Color.Blue)
    ) {
        Text("点击我")
    }
    
  2. IconButton - 图标按钮

    IconButton(onClick = { /* 点击事件 */ }) {
        Icon(Icons.Filled.Favorite, contentDescription = "收藏")
    }
    
  3. FloatingActionButton - 浮动操作按钮

    FloatingActionButton(onClick = { /* 点击事件 */ }) {
        Icon(Icons.Filled.Add, contentDescription = "添加")
    }
    

图像组件

  1. Image - 显示图片

    Image(
        painter = painterResource(R.drawable.ic_launcher),
        contentDescription = "应用图标",
        modifier = Modifier.size(50.dp)
    )
    
  2. Icon - 显示矢量图标

    Icon(
        imageVector = Icons.Filled.Home,
        contentDescription = "主页",
        tint = Color.Red
    )
    

列表组件

  1. LazyColumn - 垂直滚动列表

    LazyColumn {
        items(100) { index ->
            Text("Item #$index", modifier = Modifier.padding(16.dp))
        }
    }
    
  2. LazyRow - 水平滚动列表

    LazyRow {
        items(100) { index ->
            Text("Item #$index", modifier = Modifier.padding(16.dp))
        }
    }
    

对话框和提示

  1. AlertDialog - 警告对话框

    val openDialog = remember { mutableStateOf(true) }
    
    if (openDialog.value) {
        AlertDialog(
            onDismissRequest = { openDialog.value = false },
            title = { Text("提示") },
            text = { Text("这是一个对话框") },
            confirmButton = {
                Button(onClick = { openDialog.value = false }) {
                    Text("确定")
                }
            },
            dismissButton = {
                Button(onClick = { openDialog.value = false }) {
                    Text("取消")
                }
            }
        )
    }
    
  2. Snackbar - 底部提示

    val scaffoldState = rememberScaffoldState()
    val scope = rememberCoroutineScope()
    
    Scaffold(scaffoldState = scaffoldState) {
        Button(onClick = {
            scope.launch {
                scaffoldState.snackbarHostState.showSnackbar("这是一个Snackbar")
            }
        }) {
            Text("显示Snackbar")
        }
    }
    

其他常用组件

  1. Spacer - 空白间隔

    Column {
        Text("上边")
        Spacer(modifier = Modifier.height(16.dp))
        Text("下边")
    }
    
  2. Divider - 分割线

    Column {
        Text("第一部分")
        Divider(color = Color.Gray, thickness = 1.dp)
        Text("第二部分")
    }
    
  3. CircularProgressIndicator - 圆形进度条

    CircularProgressIndicator(
        color = Color.Blue,
        strokeWidth = 4.dp
    )
    
  4. LinearProgressIndicator - 线性进度条

    var progress by remember { mutableStateOf(0.1f) }
    LinearProgressIndicator(progress = progress)
    
  5. Switch - 开关

    var checked by remember { mutableStateOf(false) }
    Switch(
        checked = checked,
        onCheckedChange = { checked = it }
    )
    
  6. Checkbox - 复选框

    var checked by remember { mutableStateOf(false) }
    Checkbox(
        checked = checked,
        onCheckedChange = { checked = it }
    )
    
  7. RadioButton - 单选按钮

    var selected by remember { mutableStateOf("Option1") }
    Column {
        RadioButton(
            selected = selected == "Option1",
            onClick = { selected = "Option1" }
        )
        RadioButton(
            selected = selected == "Option2",
            onClick = { selected = "Option2" }
        )
    }
    
  8. Slider - 滑块

    var sliderPosition by remember { mutableStateOf(0f) }
    Slider(
        value = sliderPosition,
        onValueChange = { sliderPosition = it },
        valueRange = 0f..100f,
        steps = 5
    )
    

修饰符(Modifier)常用方法

  1. 尺寸设置

    Modifier
        .size(100.dp) // 固定尺寸
        .width(100.dp) // 固定宽度
        .height(100.dp) // 固定高度
        .fillMaxWidth() // 最大宽度
        .fillMaxHeight() // 最大高度
        .fillMaxSize() // 最大尺寸
    
  2. 边距和内边距

    Modifier
        .padding(8.dp) // 所有方向
        .padding(horizontal = 8.dp, vertical = 4.dp) // 指定方向
        .margin(8.dp) // 外边距
    
  3. 背景和边框

    Modifier
        .background(Color.Blue) // 背景色
        .border(2.dp, Color.Red) // 边框
        .clip(RoundedCornerShape(8.dp)) // 圆角裁剪
    
  4. 点击和交互

    Modifier
        .clickable { /* 点击事件 */ }
        .combinedClickable(
            onClick = { /* 单击 */ },
            onDoubleClick = { /* 双击 */ },
            onLongClick = { /* 长按 */ }
        )
    
  5. 滚动和布局

    Modifier
        .verticalScroll(rememberScrollState()) // 垂直滚动
        .horizontalScroll(rememberScrollState()) // 水平滚动
        .weight(1f) // 权重布局
    

Compose 高级组件与优化技巧

高级组件补充

1. 高级布局组件

ConstraintLayout - 约束布局(适合复杂布局)

ConstraintLayout(modifier = Modifier.fillMaxSize()) {
    val (button, text) = createRefs()
    
    Button(
        onClick = { /* ... */ },
        modifier = Modifier.constrainAs(button) {
            top.linkTo(parent.top)
            start.linkTo(parent.start)
            end.linkTo(parent.end)
        }
    ) {
        Text("居中按钮")
    }
    
    Text(
        "下方文本",
        modifier = Modifier.constrainAs(text) {
            top.linkTo(button.bottom, margin = 16.dp)
            start.linkTo(parent.start)
            end.linkTo(parent.end)
        }
    )
}

CustomLayout - 自定义布局

@Composable
fun CustomLayout() {
    Layout(
        content = {
            Box(Modifier.background(Color.Red))
            Box(Modifier.background(Color.Blue))
            Box(Modifier.background(Color.Green))
        }
    ) { measurables, constraints ->
        // 自定义测量和布局逻辑
        val placeables = measurables.map { it.measure(constraints) }
        layout(constraints.maxWidth, constraints.maxHeight) {
            placeables.forEachIndexed { index, placeable ->
                placeable.placeRelative(
                    x = index * 100,
                    y = index * 100
                )
            }
        }
    }
}

2. 高级列表功能

LazyColumn/LazyRow 粘性头部

LazyColumn {
    stickyHeader {
        Text("分类1", modifier = Modifier.background(Color.LightGray))
    }
    items(10) { index -> Text("项目 $index") }
    
    stickyHeader {
        Text("分类2", modifier = Modifier.background(Color.LightGray))
    }
    items(10) { index -> Text("项目 ${index + 10}") }
}

多类型列表

sealed class ListItem {
    data class Header(val title: String) : ListItem()
    data class Content(val text: String) : ListItem()
}

val items = listOf(
    ListItem.Header("第一部分"),
    ListItem.Content("内容1"),
    // ...
)

LazyColumn {
    items(items) { item ->
        when (item) {
            is ListItem.Header -> Text(item.title, style = MaterialTheme.typography.h6)
            is ListItem.Content -> Text(item.text)
        }
    }
}

3. 动画组件

AnimatedVisibility - 显隐动画

var visible by remember { mutableStateOf(false) }

AnimatedVisibility(
    visible = visible,
    enter = fadeIn() + expandVertically(),
    exit = fadeOut() + shrinkVertically()
) {
    Text("动画显示的内容")
}

animate*AsState - 值动画

var enabled by remember { mutableStateOf(false) }
val backgroundColor by animateColorAsState(
    if (enabled) Color.Green else Color.Red
)

Box(
    Modifier
        .size(100.dp)
        .background(backgroundColor)
        .clickable { enabled = !enabled }
)

4. 手势处理

高级手势检测

var offset by remember { mutableStateOf(Offset.Zero) }
Box(
    Modifier
        .size(100.dp)
        .background(Color.Blue)
        .offset { IntOffset(offset.x.roundToInt(), offset.y.roundToInt()) }
        .pointerInput(Unit) {
            detectDragGestures { change, dragAmount ->
                offset += dragAmount
            }
        }
)

多点触控

var scale by remember { mutableStateOf(1f) }
Box(
    Modifier
        .size(100.dp)
        .background(Color.Blue)
        .scale(scale)
        .pointerInput(Unit) {
            detectTransformGestures { _, pan, zoom, _ ->
                scale *= zoom
            }
        }
)

性能优化技巧

1. 重组优化

使用 derivedStateOf 减少不必要的重组

val listState = rememberLazyListState()
val showButton by remember {
    derivedStateOf {
        listState.firstVisibleItemIndex > 0
    }
}

if (showButton) {
    Button(onClick = { /* 回到顶部 */ }) {
        Text("回到顶部")
    }
}

使用 key 提高列表性能

LazyColumn {
    items(items, key = { it.id }) { item ->
        ItemView(item)
    }
}

2. 延迟加载

使用 Lazy 延迟初始化

val expensiveObject by remember {
    lazy {
        // 昂贵的初始化操作
        ExpensiveObject()
    }
}

3. 状态提升

将状态提升到调用方

@Composable
fun Counter(count: Int, onIncrement: () -> Unit) {
    Button(onClick = onIncrement) {
        Text("Clicked $count times")
    }
}

@Composable
fun Parent() {
    var count by remember { mutableStateOf(0) }
    Counter(count = count, onIncrement = { count++ })
}

4. 避免反向数据流

避免在组合中修改状态

// 错误做法
@Composable
fun BadExample() {
    var count by remember { mutableStateOf(0) }
    
    LaunchedEffect(Unit) {
        count++ // 在组合中直接修改状态
    }
}

// 正确做法
@Composable
fun GoodExample(onCountChanged: (Int) -> Unit) {
    LaunchedEffect(Unit) {
        onCountChanged(1) // 通过回调通知父组件
    }
}

工具和调试

1. 使用 RecompositionCount 调试重组

@Composable
fun DebugExample() {
    val recomposeCount = remember { mutableStateOf(0) }
    recomposeCount.value++
    Text("重组次数: ${recomposeCount.value}")
}

2. 使用 Layout Inspector 检查布局层次

3. 使用 Modifier.debugInspectorInfo 自定义调试信息

Modifier
    .padding(16.dp)
    .debugInspectorInfo {
        name = "customPadding"
        value = 16.dp
    }

高级主题

1. 自定义主题

private val MyTypography = Typography(
    h1 = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Bold,
        fontSize = 30.sp
    )
    // 定义其他文本样式...
)

@Composable
fun MyTheme(content: @Composable () -> Unit) {
    MaterialTheme(
        colors = LightColors,
        typography = MyTypography,
        shapes = Shapes,
        content = content
    )
}

2. 自定义绘制

Canvas(modifier = Modifier.size(100.dp)) {
    drawCircle(
        color = Color.Blue,
        radius = size.minDimension / 2
    )
    drawLine(
        color = Color.Red,
        start = Offset(0f, 0f),
        end = Offset(size.width, size.height),
        strokeWidth = 2.dp.toPx()
    )
}

3. 与 View 系统互操作

AndroidView(
    factory = { context ->
        // 创建传统View
        TextView(context).apply {
            text = "传统View"
        }
    },
    update = { view ->
        // 更新View
        view.text = "更新后的传统View"
    }
)

这些高级组件和优化技巧可以帮助你构建更复杂、更高效的Compose应用。性能优化应该基于实际测量,而不是过早优化。使用工具分析性能瓶颈,然后有针对性地进行优化。