如何在jetpack compose Lazy Column上实现弹跳效果

Yog*_*ear 10 android android-jetpack-compose

我想在 LazyColumn 上实现“类似 iOS”的反弹效果,但不知道如何实现它。

预期结果是:类似于 Android 上的 iOS 滚动效果(使用 RecyclerView),列表顶部和底部有弹跳。

我浏览了 Chris Bane 的 snapper: https: //github.com/chrisbanes/snapper但它似乎不支持它。

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

先感谢您!

sla*_*boy 3

目前这是不可能的03.14.2022

Scrollable.kt如果您在包内的类中看到源代码,androidx.compose.foundation.gestures则有一个扩展函数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
Run Code Online (Sandbox Code Playgroud)

该方法包含OverScrollController ,它在功能上处理过度滚动,不幸的是该方法是内部方法,因此我们不能在其包之外使用它。

如果我们在 androidx.compose.foundation 包中看到Scroll.ktModifier.verticalScroll类,我们可以看到扩展方法scroll(),它也是私有的并且由and使用Modifier.horizontalScroll ,正在使用默认的过度滚动控制器

private fun Modifier.scroll(
    state: ScrollState,
    reverseScrolling: Boolean,
    flingBehavior: FlingBehavior?,
    isScrollable: Boolean,
    isVertical: Boolean
) = composed(
    factory = {
        val overScrollController = rememberOverScrollController()
  ...
Run Code Online (Sandbox Code Playgroud)
@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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

目前我们只能禁用默认的过度滚动配置,如本答案所示。或者设置自定义配置,只能设置颜色和偏移量,并且仅适用于 API < 31

 CompositionLocalProvider(
     LocalOverScrollConfiguration provides OverScrollConfiguration(
         glowColor = Color.Red, forceShowAlways = true, PaddingValues(10.dp)
     )
 ) {
     // your row, colum
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我尝试实现自己的逻辑,用于pointerInteropFilter检测偏移和verticalScroll滚动功能。但是当我包含pointerInteropFilter时,它与verticalScroll交互,并且Column变得滞后并且无法检测到正确的事件!

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)
){
    
} 
Run Code Online (Sandbox Code Playgroud)

因此,谷歌是否允许自定义过度滚动效果,并希望在未来,他们会为此做点什么!