带有滑动手势的运动布局 + SwipeRefreshLayout + RecyclerView 错误行为向上滚动

And*_*pek 7 android android-animation android-layout android-recyclerview android-motionlayout

我正在使用 MotionLayout 构建包含 2 个部分的 UI - 顶部有一些视图,底部有 SwipeRefresh 和 RecyclerView 内部。另外,我有一个 MotionLayout 手势 - SwipeRefresh 在向上滑动时向上移动到顶视图上方。问题是当我将 RecyclerView 滚动到底部(顶视图“折叠”)然后到顶部时 - MotionLayout 开始立即反转我的过渡(“展开”) - 当 RecyclerView 没有完全滚动到顶部而不是滚动 RecyclerView第一的。当我的 SwipeRefresh 正在更新或刷新时,它可以正常工作。禁用它会导致刷新布局进度条在没有动画的情况下消失 - 这不是一个好的解决方案。任何解决方法?

布局 xml 要点

布局场景要点

mue*_*flo 11

我在浏览 MotionLayout 的官方错误修复历史时遇到了同样的问题并提出了一个解决方案。你必须onNestedPreScroll像这样覆盖MotionLayout的方法:

/**
 * The current version of motionLayout (2.0.0-beta04) does not honor the position
 * of the RecyclerView, if it is wrapped in a SwipeRefreshLayout.
 * This is the case for the PullRequest screen: When scrolling back to top, the motionLayout transition
 * would be triggered immediately instead of only as soon as the RecyclerView scrolled back to top.
 *
 * This workaround checks if the SwipeRefresh layout can still scroll back up. If so, it does not trigger the motionLayout transition.
 */
class SwipeRefreshMotionLayout : MotionLayout {

    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun onNestedPreScroll(target: View, dx: Int, dy: Int, consumed: IntArray, type: Int) {
        if (!isInteractionEnabled) {
            return
        }

        if (target !is SwipeRefreshLayout) {
            return super.onNestedPreScroll(target, dx, dy, consumed, type)
        }

        val recyclerView = target.getChildAt(0)
        if (recyclerView !is RecyclerView) {
            return super.onNestedPreScroll(target, dx, dy, consumed, type)
        }

        val canScrollVertically = recyclerView.canScrollVertically(-1)
        if (dy < 0 && canScrollVertically) {
            // don't start motionLayout transition
            return;
        }

        super.onNestedPreScroll(target, dx, dy, consumed, type)
    }
}
Run Code Online (Sandbox Code Playgroud)

将此 MotionLayout 与 SwipeRefreshLayout 结合使用对我来说效果很好。我也在这里发布了这个,以防你想跟踪谷歌的错误修复。


归档时间:

查看次数:

2614 次

最近记录:

5 年,6 月 前