如何在Jetpack Compose的Lazy Column中实现弹跳效果

8

我想在LazyColumn上实现一个弹跳“iOS-like”的效果,但不知道如何实现。

期望的结果是:使用RecyclerView实现Android上的iOS类似的超滚动效果,并在列表顶部和底部有弹跳效果。

我查看了Chris Bane的snapper:https://github.com/chrisbanes/snapper,但它似乎不支持此功能。

我的猜测是我需要创建一些LazyListScope扩展,但很难弄清楚。

提前感谢!

1个回答

3

目前不可能 2022年3月14日

如果您查看位于androidx.compose.foundation.gestures包内的Scrollable.kt类的源代码,则会发现一个扩展函数Modifier.scrollable

internal fun Modifier.scrollable(
    state: ScrollableState,
    orientation: Orientation,
    overScrollController: OverScrollController?,
    enabled: Boolean = true,
    reverseDirection: Boolean = false,
    flingBehavior: FlingBehavior? = null,
    interactionSource: MutableInteractionSource? = null
): Modifier

这个方法包含OverScrollController,用于处理过度滚动功能,但不幸的是,该方法是内部的,因此我们无法在其包外使用它。
如果我们查看androidx.compose.foundation包中的Scroll.kt类,我们可以看到扩展方法scroll(),它也是私有的,并被Modifier.verticalScrollModifier.horizontalScroll使用,使用默认的过度滚动控制器。
private fun Modifier.scroll(
    state: ScrollState,
    reverseScrolling: Boolean,
    flingBehavior: FlingBehavior?,
    isScrollable: Boolean,
    isVertical: Boolean
) = composed(
    factory = {
        val overScrollController = rememberOverScrollController()
  ...

@Composable
@OptIn(ExperimentalFoundationApi::class)
internal actual fun rememberOverScrollController(): OverScrollController {
    val context = LocalContext.current
    val config = LocalOverScrollConfiguration.current
    return remember(context, config) {
        if (config != null) {
            AndroidEdgeEffectOverScrollController(context, config)
        } else {
            NoOpOverscrollController
        }
    }
}

此时我们只能禁用默认的过度滚动配置,如answer所示。或设置自定义配置,仅可设置颜色和偏移量,并且仅适用于API < 31。
 CompositionLocalProvider(
     LocalOverScrollConfiguration provides OverScrollConfiguration(
         glowColor = Color.Red, forceShowAlways = true, PaddingValues(10.dp)
     )
 ) {
     // your row, colum
}

enter image description here

我尝试使用pointerInteropFilter来检测偏移量,使用verticalScroll实现滚动功能。但是当我包含pointerInteropFilter时,它会与verticalScroll产生交互,导致列变得卡顿,并且无法正确检测事件!
Column(
    verticalArrangement = Arrangement.SpaceEvenly,
    horizontalAlignment = Alignment.CenterHorizontally,
    modifier = Modifier
        .fillMaxSize()
        .offset {
            IntOffset(0, offset.roundToInt())
        } 
        .pointerInteropFilter { motionEvent ->    
            
            when (motionEvent.action) {
                MotionEvent.ACTION_DOWN -> {
                    startFingerPositionY = motionEvent.rawY
                }
                MotionEvent.ACTION_MOVE, MotionEvent.ACTION_UP -> {
                    offsetY = startFingerPositionY - motionEvent.rawY
                    startFingerPositionY = motionEvent.rawY    
           
                }
            }    
            true 
        }
        .verticalScroll(state = state)
){
    
} 

所以这取决于Google是否允许自定义超出滚动效果,希望在未来他们能够采取一些行动!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接