Compose LazyGrid(LazyVerticalGrid/LazyHorizontalGrid) 滑动事件和拖拽事件冲突

背景

我们需要实现纵向滑动的网格列表,同时我们需要实现条目的长按拖拽功能。

问题

当长按后拖拽方向是纵向,则会与纵向滑动事件发生冲突。此时,LazyVerticalGrid就会优先处理纵向滑动,长按拖拽失效。

原因

通过在detectDragGesturesAfterLongPress的回调中添加日志,如下:

Modifier.pointerInput(Unit) {
    detectDragGesturesAfterLongPress(
        onDragStart = {
            Log.d(TAG, "detectDragGesturesAfterLongPress onDragStart")
        },
        onDragEnd = {
            Log.d(TAG, "detectDragGesturesAfterLongPress onDragEnd")
        },
        onDragCancel = {
            Log.d(TAG, "detectDragGesturesAfterLongPress onDragCancel")
        },
        onDrag = { change, dragAmount ->
            Log.d(TAG, "detectDragGesturesAfterLongPress onDrag")
        })
})

通过调试发现以下规律:

1. 当可以正常拖拽时,日志如下
2024-05-07 10:05:09.828 detectDragGesturesAfterLongPress onDragStart
2024-05-07 10:05:10.928 detectDragGesturesAfterLongPress onDrag
2024-05-07 10:05:10.943 detectDragGesturesAfterLongPress onDrag
2024-05-07 10:05:11.225 detectDragGesturesAfterLongPress onDrag
2024-05-07 10:05:11.239 detectDragGesturesAfterLongPress onDrag
2024-05-07 10:05:11.428 detectDragGesturesAfterLongPress onDrag
2024-05-07 10:05:11.444 detectDragGesturesAfterLongPress onDrag
2024-05-07 10:05:11.584 detectDragGesturesAfterLongPress onDrag
2024-05-07 10:05:11.613 detectDragGesturesAfterLongPress onDragEnd

2. 当进行纵向拖拽时,日志如下
2024-05-07 10:04:57.589 detectDragGesturesAfterLongPress onDragStart
2024-05-07 10:04:58.402 detectDragGesturesAfterLongPress onDragCancel

通过以上规律,发现当拖拽方向和滑动方向一致时,detectDragGesturesAfterLongPress的onDrag回调并不会执行。所以我个人猜测原因是,Compose框架在这种情况下,并未处理好事件冲突。(欢迎大神们来指教一下,分析一下原因)

解决方法

还好,Compose的LazyVerticalGrid可组合项为我们预留了userScrollEnabled参数,我们通过动态配置该参数,即可解决这个问题。也就是说,在我们在检测到长按事件时,设置userScrollEnabled = false,当拖拽结束时,我们再设置userScrollEnabled = true

@Composable
fun LazyVerticalGrid(
    columns: GridCells,
    modifier: Modifier = Modifier,
    state: LazyGridState = rememberLazyGridState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    verticalArrangement: Arrangement.Vertical =
        if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    userScrollEnabled: Boolean = true,
    content: LazyGridScope.() -> Unit
)


 

  • 12
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值