如何在Jetpack Compose中实现类OneUI风格的图标形状?
在Jetpack Compose中实现OneUI图标形状
自定义Shape实现目标样式
三星OneUI的图标形状不是标准Squircle,它的圆角过渡更平缓,接近圆角矩形但边角有独特的曲线弧度。你可以通过自定义Shape类,用Path手动绘制这个形状:
import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Outline import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp class OneUiIconShape(private val cornerRadius: Float = 24.dp.toPx()) : Shape { override fun createOutline( size: Size, layoutDirection: LayoutDirection, density: Density ): Outline { val path = Path().apply { val width = size.width val height = size.height val corner = cornerRadius.coerceAtMost(minOf(width, height) / 2) // 左上角曲线 moveTo(corner, 0f) cubicTo(0f, 0f, 0f, corner, 0f, corner) // 左边缘直线 lineTo(0f, height - corner) // 左下角曲线 cubicTo(0f, height, corner, height, corner, height) // 下边缘直线 lineTo(width - corner, height) // 右下角曲线 cubicTo(width, height, width, height - corner, width, height - corner) // 右边缘直线 lineTo(width, corner) // 右上角曲线 cubicTo(width, 0f, width - corner, 0f, width - corner, 0f) // 闭合路径 close() } return Outline.Generic(path) } }
在Compose里直接用这个Shape就行:
Box( modifier = Modifier .size(64.dp) .background(Color.Blue, shape = OneUiIconShape()) ) { // 这里放图标内容,比如Icon组件 }
三星OneUI的实现思路
三星官方的OneUI图标形状,大概率是靠自定义贝塞尔曲线精准控制边角弧度实现的,不是用系统自带的Squircle。他们可能会根据图标尺寸动态调整曲线控制点,保证不同大小下形状一致。另外OneUI还支持切换图标形状,底层都是通过不同的Path曲线来实现不同样式的边角。
你用Squircle没成功很正常,因为标准Squircle的曲线公式和OneUI的不一样——Squircle是完全椭圆化的圆角,而OneUI的边角更偏向“圆角矩形+平缓的曲线过渡”,必须自定义Path才能匹配上。
内容的提问来源于stack exchange,提问作者imn
相关产品推荐
相关产品推荐

