使用Jetpack Compose完成自定义手势处理,高级安卓面试题

// 双击

},

onLongPress = { offset: Offset ->

// 长按

},

onPress = { offset: Offset ->

// 按下

},

onTap = { offset: Offset ->

// 轻触

}

)

}

)

}

}

变换类型基础 API

API 介绍

| API名称 | 作用 |

| — | — |

| detectTransformGestures | 监听拖动、缩放与旋转手势 |

Transfomer Modifier 不同的是,通过这个 API 可以监听单指的拖动手势,和拖动类型基础 API所提供的功能一样,除此之外还支持监听双指缩放与旋转手势。反观Transfomer Modifier 只能监听到双指拖动手势,不知设计成这样的行为不一致是否是 Google 有意而为之。

举例说明

接下来我们为这个绿色方块添加变化手势处理逻辑。detectTransformGestures 方法提供了两个参数。

panZoomLock(可选): 当拖动或缩放手势发生时是否支持旋转

onGesture(必须):当拖动、缩放或旋转手势发生时回调

suspend fun PointerInputScope.detectTransformGestures(

panZoomLock: Boolean = false,

onGesture: (centroid: Offset, pan: Offset, zoom: Float, rotation: Float) -> Unit

)

💡 Tips

关于偏移、缩放与旋转,我们建议的调用顺序是 rotate -> scale -> offset

  1. 若offset发生在rotate之前时,rotate会对offset造成影响。具体表现为当出现拖动手势时,组件会以当前角度为坐标轴进行偏移。
  1. 若offset发生在scale之前是,scale也会对offset造成影响。具体表现为UI组件在拖动时不跟手

@Preview

@Composable

fun TransformGestureDemo() {

var boxSize = 100.dp

var offset by remember { mutableStateOf(Offset.Zero) }

var ratationAngle by remember { mutableStateOf(0f) }

var scale by remember { mutableStateOf(1f) }

Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {

Box(Modifier

.size(boxSize)

.rotate(ratationAngle) // 需要注意offset与rotate的调用先后顺序

.scale(scale)

.offset {

IntOffset(offset.x.roundToInt(), offset.y.roundToInt())

}

.background(Color.Green)

.pointerInput(Unit) {

detectTransformGestures(

panZoomLock = true, // 平移或放大时是否可以旋转

onGesture = { centroid: Offset, pan: Offset, zoom: Float, rotation: Float ->

offset += pan

scale *= zoom

ratationAngle += rotation

}

)

}

)

}

}

transform

forEachGesture

在传统 View 系统中,一次手指按下、移动到抬起过程中的所有手势事件可以共同构成一个手势事件序列。我们可以通过自定义手势处理来对于每一个手势事件序列进行定制处理。Compose 提供了 forEachGesture 以允许用户可以对每一个手势事件序列进行相同的定制处理。如果我们忘记使用 forEachGesture ,那么只会处理第一次手势事件序列。有些同学可能会问,为什么我不能在手势处理逻辑最外层套一层 while(true) 呢,通过 forEachGesture 的实现我们可以看到 forEachGesture 其实内部也是由while 实现的,除此之外他保证了协程只有存活时才能监听手势事件,同时也保证了每次交互结束时所有手指都是离开屏幕的。有些同学看到 while 可能新生疑问,难道这样不会阻塞主线程嘛?其实我们在介绍 PointerInput Modifier 时就提到过,我们的手势操作处理均发生在协程中。其实前面我们所提到的绝大多数 API

  • 16
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值