技术探索:开源分享 - 在Jetpack Compose中实现iOS丝滑左滑菜单交互设计

背景

最近遇到个需求,jetpack compose中要给列表的item加一个左滑删除菜单,左滑展示一个删除按钮,点击删除item,很简单的需求,然而Google了一圈,只发现了compose自带的SwipeToDismiss和类似的一个开源库me.saket.swipe:swipe比较有用,但是细看不太符合需求,SwipeToDismiss顾名思义就是滑动到某个地方item就会dismiss,不符合要求的swipe后点击再dismiss的需求啊(测试不接受你有啥办法),自己动手呗!!

swipe这个库写得比较简单且支持compose multiplatform,果断在这个库的基础上来修改。

先上成果

少啰嗦,先看东西!觉得有用的话给个star呗~

swipe-like-ios

swipe-like-ios builds composables that can be swiped left or right for revealing actions

groovy 复制代码
// settings.gradle.kts
repositories {
  maven { setUrl("https://www.jitpack.io") }
}

// build.gradle.kts
implementation("com.linversion.swipe:swipe-like-ios:latest-version")
kotlin 复制代码
val archive = SwipeAction(
  icon = rememberVectorPainter(Icons.TwoTone.Archive),
  background = Color.Green,
  onClick = { ... }
)

val replyAll = SwipeAction(
  icon = rememberVectorPainter(Icons.TwoTone.ReplyAll),
  background = Color.Perfume,
  onClick = { println("Reply swiped") }
)
  
val snooze = SwipeAction(
  icon = { Text("Snooze") },
  background = Color.Yellow,
  onClick = { ... },
)

SwipeableActionsBox(
  startActions = listOf(replyAll),
  endActions = listOf(snooze, archive),
  swipeThreshold = 80.dp,
) {
  // Swipeable content goes here.
}

简单介绍一下实现原理

其实很简单,就是在item的左右两边分别用一个Row放置你的菜单(action),给个初始的offsetX,使得菜单刚好不可见,滑动的时候改变ofssetX,每个action平分滑动的空间,直到菜单完全展示后加一个阻尼的效果,完全仿照iOS的实现。

对比之下SwipeToDismiss的原理是在item的底部放一个Row来摆放你的action,滑动的时候就可以看到了。

滑动的监听则都是用Modifier的draggable修饰符,然后给item设置absoluteOffset

kotlin 复制代码
Box(
    modifier = Modifier
      .absoluteOffset { IntOffset(x = offsetX, y = 0) }
      .draggable(
        orientation = Horizontal,
        enabled = !state.isResettingOnRelease,
        onDragStopped = {
          scope.launch {
            state.handleOnDragStopped()
          }
        },
        state = state.draggableState,
      ),
    content = content
  )

后续期望

仔细看了一下,iOS在有些场景也有SwipeToDismiss的效果,并且加了震动效果,后续会考虑拓展加上这个效果。

相关推荐
一条Go14 小时前
能力套餐:菜单、权限、开通范围怎么拆成三层而不打架
后端·github·saas
WeWorker15 小时前
浏览器 Agent 的两种宿命:像素派和工具派
github
GitHub实测笔记15 小时前
hyperfine 本机实测:2.96MB 上 bat 开高亮中位数 2.39s、cat 3.0ms(约 870 倍);v2 默认不走 shell
github
90后的晨仔15 小时前
解决 Android 构建报错:Unable to delete file .../file-map.txt
android·前端
mg66815 小时前
安卓玩机工具----安卓手机变成桌面电脑!多窗口镜像+音频投射+游戏操控,无需 Root
android·智能手机·电脑
peakmain916 小时前
异常处理 - Native 层的崩溃捕获机制及实现 (一)
android·性能优化
木头左17 小时前
【Android】听写播放器改版:中英文书写速度拆项与「正在读」高亮
android·room·media3·jetpack compose·听写
徐小夕17 小时前
万字长文!DeepSeek Super-agent × 企业知识库架构深度拆解与落地实践
前端·vue.js·github
奶油话梅糖17 小时前
打开项目 0.9 秒、内存只有 IDEA 的 1/12:OpenIDEA 用 Rust 把 IntelliJ IDEA 重造了一遍
java·rust·github·intellij-idea