Ví dụ về kiểu

Tài liệu sau đây chứa ví dụ về cách sử dụng Kiểu để tạo một số loại thành phần nhất định.

Nút

Bạn có thể dùng các kiểu để tạo nhiều loại nút có thể khác với các thành phần Material tiêu chuẩn.

Nút cơ bản

Hãy xem xét nút sau đây được xác định là cơ sở cho nhiều loại nút:

@Composable
fun BaseButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    style: Style = Style,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource? = remember {
        MutableInteractionSource()
    },
    content: @Composable RowScope.() -> Unit
) {
    val styleState = rememberUpdatedStyleState(interactionSource) {
        it.isEnabled = enabled
    }
    Row(
        modifier = modifier
            .semantics(properties = {
                role = Role.Button
            })
            .clickable(
                enabled = enabled,
                onClick = onClick,
                interactionSource = interactionSource,
                indication = null,
            )
            .styleable(styleState, baseButtonStyle, style),
        content = content,
        verticalAlignment = Alignment.CenterVertically
    )
}

Nút dịch nền khi di chuột

Để xác định một nút có nền di chuyển khi di chuột, hãy sử dụng đoạn mã sau:

Hình 1. Nút có nền dịch khi di chuột.

@Preview
@Composable
fun HoverButtonExample() {
    Box(
        modifier = Modifier.padding(32.dp),
        contentAlignment = Alignment.Center
    ) {
        BaseButton(
            onClick = {},
            style = Style {
                background(Color.Transparent)
                shape(RoundedCornerShape(0.dp))
                border(1.dp, Color.Black)
                contentColor(Color.Black)
                fontSize(16.sp)
                fontWeight(FontWeight.Light)
                letterSpacing(1.sp)
                contentPadding(vertical = 13.dp, horizontal = 20.dp)
                dropShadow(
                    Shadow(
                        spread = 0.dp, color = Color(0xFFFFE54C),
                        radius = 0.dp,
                        offset = DpOffset(7.dp, 7.dp)
                    )
                )
                hovered {
                    animate(tween(200)) {
                        dropShadow(
                            Shadow(
                                spread = 0.dp, color = Color(0xFFFFE54C),
                                radius = 0.dp,
                                offset = DpOffset(0.dp, 0.dp)
                            )
                        )
                    }
                }
                pressed {
                    animate(tween(200)) {
                        dropShadow(
                            Shadow(
                                spread = 0.dp, color = Color(0xFFFFE54C),
                                radius = 0.dp,
                                offset = DpOffset(0.dp, 0.dp)
                            )
                        )
                    }
                }
            }
        ) {
            BaseText("Button 52")
        }
    }
}

Nút có độ sâu bo tròn với ảnh động đổ bóng

Để tạo một nút có hiệu ứng nhấn sâu giúp dịch chuyển bóng lên và xuống trên pressed, bạn có thể thực hiện theo cách sau:

Hình 2. Nút có hiệu ứng chiều sâu, dịch lớp bóng đổ khi nhấn.

@Preview
@Composable
fun ShadowAnimationButton() {
    Box(modifier = Modifier.padding(32.dp)) {
        val density = LocalDensity.current
        val buttonStyle = Style {
            background(Color(0xFFFBEED0))
            border(2.dp, Color(0xFF422800))
            shape(RoundedCornerShape(30.dp))
            dropShadow(
                Shadow(
                    color = Color(0xFF422800), offset = DpOffset(4.dp, 4.dp),
                    radius = 0.dp, spread = 0.dp
                )
            )
            contentColor(Color(0xFF422800))
            fontWeight(FontWeight.SemiBold)
            fontSize(18.sp)
            contentPaddingHorizontal(25.dp)
            externalPadding(8.dp)
            height(50.dp)
            textAlign(TextAlign.Center)
            hovered {
                animate {
                    background(Color.White)
                }
            }
            pressed {
                animate {
                    dropShadow(
                        Shadow(
                            color = Color(0xFF422800),
                            offset = DpOffset(2.dp, 2.dp),
                            radius = 0.dp,
                            spread = 0.dp
                        )
                    )
                    translation(with(density) { 2.dp.toPx() }, with(density) { 2.dp.toPx() })
                }
            }
        }
        BaseButton(
            onClick = {},
            style = buttonStyle
        ) {
            BaseText("Button 74")
        }
    }
}

Nhiều kiểu xếp lớp có ảnh động khi nhấn

Đoạn mã sau đây tạo một nút có hiệu ứng nhấn theo chiều sâu bằng Styles, có nhiều lớp kiểu và tất cả đều sử dụng cùng một StyleState:

Hình 3. Nút có hiệu ứng nhấn chìm và nhiều lớp kiểu.

@Preview
@Composable
fun MultipleStylesButton() {
    val interactionSource = remember { MutableInteractionSource() }
    val styleState = remember(interactionSource) { MutableStyleState(interactionSource) }
    val density = LocalDensity.current

    Box(
        modifier = Modifier
            .styleable(styleState) {
                size(200.dp, 48.dp)
                externalPadding(32.dp)
            }
            .clickable(interactionSource, indication = null) {},
        contentAlignment = Alignment.Center
    ) {
        val edgeStyle = Style {
            fillSize()
            shape(RoundedCornerShape(16.dp))
            background(Color(0xFF1CB0F6))
        }

        val frontStyle = Style {
            fillSize()
            background(Color(0xFF1899D6))
            shape(RoundedCornerShape(16.dp))
            contentPadding(vertical = 12.dp, horizontal = 16.dp)
            translationY(with(density) { (-4).dp.toPx() })
            pressed {
                animate {
                    translationY(with(density) { (0).dp.toPx() })
                }
            }
        }
        Box(modifier = Modifier.semantics(properties = {
            role = Role.Button
        }).styleable(styleState, edgeStyle)) {
            Box(
                modifier = Modifier
                    .styleable(styleState, frontStyle),
                contentAlignment = Alignment.Center
            ) {
                BaseText(
                    "Button 19".toUpperCase(Locale.current),
                    style = Style {
                        contentColor(Color.White)
                        fontSize(15.sp)
                        fontWeight(FontWeight.Bold)
                        letterSpacing(0.8.sp)
                    }
                )
            }
        }
    }
}