Compose中常用的一些Modifier的扩展ui方法记录

Compose中常用的一些Modifier的扩展ui方法记录

关于

  本篇主要记录一些开发中可能用到的常用方法的扩展记录,包括防快速带点击,画虚实线divider,画虚线边框,绘制阴影等。

防快速点击

inline fun Modifier.singleClickable(
    debounceDuration: Long = 400L,
    enabled: Boolean = true,//中间这三个是clickable自带的参数
    rippleEnabled: Boolean = true, //是否开启水波纹
    onClickLabel: String? = null,
    role: Role? = null,
    crossinline onClick: () -> Unit
): Modifier = composed {
   
   
    var lastClickTime by remember {
   
    mutableStateOf(value = 0L) }
    val eventAction: () -> Unit = {
   
   
        val currentTimeMillis = System.currentTimeMillis()
        if (currentTimeMillis - debounceDuration >= lastClickTime) {
   
   
            onClick()
            lastClickTime = currentTimeMillis
        }
    }
    if (rippleEnabled) {
   
   
        clickable(enabled, onClickLabel, role, eventAction)
    } else {
   
   
        clickable(
            interactionSource = NoRippleInteractionSource(),
            indication = null,
            enabled = enabled,
            onClickLabel = onClickLabel,
            role = role,
            onClick = eventAction
        )
    }
}

class NoRippleInteractionSource : MutableInteractionSource {
   
   

    override val interactions: Flow<Interaction> = emptyFlow()

    override suspend fun emit(interaction: Interaction) {
   
   }

    override fun tryEmit(interaction: Interaction) = true

}

虚实分割线

<think>我们被要求使用Jetpack Compose实现一个动态时钟界面。根据引用[1]和引用[2],我们知道Jetpack Compose是一个声明式UI工具包,特别适合构建动态和动画效果。引用[1]中的ComposeClock项目展示了如何用粒子动画表示时间,引用[2]中的Kitchen Timer则展示了倒计时动画。 实现动态时钟的基本思路: 1. 我们需要一个能够每秒更新一次的时钟,以显示当前时间(时、分、秒)。 2. 可以使用`remember`和`mutableStateOf`来保存当前时间,并使用一个定时器(如`LaunchedEffect`)来每秒更新。 3. 绘制时钟表盘,包括时针、分针、秒针以及刻度。 步骤: a. 创建一个表示当前时间的状态。 b. 启动一个协程,每秒更新一次时间。 c. 使用Compose的Canvas绘制表盘和指针。 由于用户要求动态时钟,我们主要关注如何绘制一个传统的模拟时钟(带有时针、分针、秒针的圆形表盘)。 以下是一个简单的实现示例:</think>### Jetpack Compose 实现动态时钟界面教程 在 Jetpack Compose 中实现动态时钟界面,关键在于结合 `Canvas` 绘图和状态管理实现实时更新。以下是完整实现步骤: #### 1. **创建时钟数据类** ```kotlin data class ClockTime( val hours: Float, // 0-23 转换为角度 val minutes: Float, // 0-59 转换为角度 val seconds: Float // 0-59 转换为角度 ) ``` #### 2. **实现主时钟组件** ```kotlin @Composable fun AnalogClock() { // 获取当前时间并转换为角度 val currentTime by remember { mutableStateOf(getCurrentTime()) } // 每秒更新时间(动态效果核心) LaunchedEffect(Unit) { while (true) { delay(1000) // 每秒更新 currentTime = getCurrentTime() } } // 绘制表盘 Canvas(modifier = Modifier.size(300.dp)) { drawClockFace() drawHand(currentTime.hours, 0.5f, 8f, Color.Black) // 时针 drawHand(currentTime.minutes, 0.7f, 6f, Color.DarkGray) // 分针 drawHand(currentTime.seconds, 0.8f, 4f, Color.Red) // 秒针 } } // 辅助函数:获取当前时间角度 private fun getCurrentTime(): ClockTime { val calendar = Calendar.getInstance() return ClockTime( hours = (calendar.get(Calendar.HOUR) * 30).toFloat(), minutes = (calendar.get(Calendar.MINUTE) * 6).toFloat(), seconds = (calendar.get(Calendar.SECOND) * 6).toFloat() ) } // 绘制表盘刻度 private fun DrawScope.drawClockFace() { drawCircle(color = Color.White, radius = size.minDimension / 2) for (i in 0 until 12) { val angle = i * 30f val start = Offset( x = center.x + cos(angle.degrees) * (size.minDimension / 2 - 20), y = center.y + sin(angle.degrees) * (size.minDimension / 2 - 20) ) drawCircle( color = Color.Black, center = start, radius = 4f ) } } // 绘制指针 private fun DrawScope.drawHand( angle: Float, lengthFactor: Float, strokeWidth: Float, color: Color ) { val end = Offset( x = center.x + cos(angle.degrees) * (size.minDimension / 2 * lengthFactor), y = center.y + sin(angle.degrees) * (size.minDimension / 2 * lengthFactor) ) drawLine( color = color, start = center, end = end, strokeWidth = strokeWidth.toPx(), cap = StrokeCap.Round ) } // 角度转换扩展 private val Float.degrees: Float get() = (this - 90f) * (PI.toFloat() / 180f) ``` #### 3. **添加动画效果(可选增强)** ```kotlin // 在drawHand函数中添加动画 val animatedAngle by animateFloatAsState( targetValue = angle, animationSpec = tween(durationMillis = 500) // 500ms平滑过渡 ) // 使用animatedAngle替代原始angle ``` #### 4. **在Activity中使用** ```kotlin class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { YourTheme { // 应用主题 Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { AnalogClock() } } } } } ``` #### 关键实现说明: 1. **状态管理**:使用 `mutableStateOf` 跟踪时间,`LaunchedEffect` 实现每秒更新 2. **Canvas绘图**: - `drawCircle` 绘制表盘和刻度 - `drawLine` 绘制时钟指针 - 通过三角函数计算指针端点坐标 3. **动画优化**:`animateFloatAsState` 使指针移动更平滑 4. **角度转换**:将时间转换为角度(每小时30°,每分钟6°,每秒6°) #### 进阶优化建议: 1. 添加数字刻度:使用 `drawText` 在表盘绘制数字 2. 实现粒子效果:参考 ComposeClock 项目[^1],用粒子动画表示时间流动 3. 支持主题切换:通过 `MaterialTheme` 实现亮/暗模式适配 4. 添加触控交互:用 `pointerInput` 实现时间调整功能 > 效果展示:最终实现将显示一个传统表盘,三根指针实时反映当前时间,秒针以红色突出显示,指针移动带有平滑动画效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪の星空朝酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值