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? = null, content: @Composable RowScope.() -> Unit ) { val effectiveInteractionSource = interactionSource ?: remember { MutableInteractionSource() } val styleState = remember(effectiveInteractionSource) { MutableStyleState(effectiveInteractionSource) } styleState.isEnabled = enabled Row( modifier = modifier .semantics(properties = { role = Role.Button }) .clickable( enabled = enabled, onClick = onClick, interactionSource = effectiveInteractionSource, 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:
@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:
@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 sâu bằng Styles, có nhiều lớp kiểu, tất cả đều sử dụng cùng một StyleState:
@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) } ) } } } }
Nút hiệu ứng phát sáng chuyển màu
Để đạt được hiệu ứng phát sáng chuyển màu và có thể tạo hiệu ứng động vô hạn, bạn có thể sử dụng Styles (Kiểu) kết hợp với rememberInfiniteTransition, như sau:
@Preview @Composable fun GradientGlowButtonExample() { val infiniteTransition = rememberInfiniteTransition(label = "glowing_button_85_animation") val animatedProgress by infiniteTransition.animateFloat( initialValue = 0f, targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(durationMillis = 20000, easing = LinearEasing), ), label = "progress" ) val gradientColors = listOf( Color(0xffff0000), Color(0xffff7300), Color(0xfffffb00), Color(0xff48ff00), Color(0xff00ffd5), Color(0xff002bff), Color(0xff7a00ff), Color(0xffff00c8), Color(0xffff0000) ) val glowingBrush = remember(animatedProgress) { object : ShaderBrush() { override fun createShader(size: Size): Shader { val width = size.width * 4 val brushSize = width * animatedProgress return LinearGradientShader( colors = gradientColors, from = Offset(brushSize, 0f), to = Offset(brushSize + width, 0f), tileMode = TileMode.Repeated ) } } } Box( modifier = Modifier .padding(32.dp), contentAlignment = Alignment.Center ) { BaseButton( onClick = { }, style = Style { dropShadow( Shadow( brush = glowingBrush, radius = 5.dp ) ) transformOrigin(TransformOrigin.Center) pressed { animate { dropShadow( Shadow( brush = glowingBrush, radius = 10.dp ) ) scale(0.95f) } } size(width = 200.dp, height = 50.dp) background(Color(0xFF111111)) shape(RoundedCornerShape(10.dp)) contentColor(Color.White) contentPadding(vertical = (0.6f * 14).dp, horizontal = (2f * 14).dp) border(width = 0.dp, color = Color.Transparent) } ) { BaseText(text = "Button 85") } } }