使用滑动手势+ SwipeRefreshLayout + RecyclerView的运动布局错误行为向上滚动 [英] Motion Layout with swipe gesture + SwipeRefreshLayout + RecyclerView bug wrong behavior scrolling up

查看:236
本文介绍了使用滑动手势+ SwipeRefreshLayout + RecyclerView的运动布局错误行为向上滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using MotionLayout to build UI with 2 parts - top one with some view and bottom one with SwipeRefresh and RecyclerView inside. Also I have a single gesture for MotionLayout - SwipeRefresh moves up above top view on swipe up. The problem is when I scroll RecyclerView to the bottom (top view "collapses") and then to the top - MotionLayout starts to reverse my transition at once ("expand") - when RecyclerView is not fully scrolled to the top instead of scrolling RecyclerView first. While my SwipeRefresh is updating or refreshing it works as should. Disabling it causes refresh layout progressbar disappearing without animation - it's not a good solution. Any workarounds?

布局xml要点

布局场景要点

推荐答案

我遇到了相同的问题,并在浏览MotionLayout的官方错误修正历史记录时提出了解决方案。您必须像这样重写MotionLayout的 onNestedPreScroll 方法:

I had the same issue and came up with a solution while browsing the official bugfix history of MotionLayout. You have to override the onNestedPreScroll method of MotionLayout like this:

/**
 * 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 (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)
    }
}

将此MotionLayout与SwipeRefreshLayout结合使用对我来说效果很好。
我还发布了此此处,以防您想跟踪该错误修正由Google提供。

Using this MotionLayout in conjunction with SwipeRefreshLayout works nicely for me. I also posted this here, in case you want to keep track of the bugfix by Google.

这篇关于使用滑动手势+ SwipeRefreshLayout + RecyclerView的运动布局错误行为向上滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆