首页 > 解决方案 > 实现 OnItemTouchListener 的 RecyclerView 与 LinearLayoutManager 正常滚动

问题描述

我正在尝试实现一个用例,当用户以低速滚动时,我需要正常滚动 RecyclerView(Android LayoutManager 滚动),而当用户滚动到某个速度以上时,我需要滚动一定的额外量。

我已经实现了一个 LinearLayoutManager 如下:

public class ScrollLayoutManager extends LinearLayoutManager {
    // constructors

    @Override
    public void onAttachedToWindow(RecyclerView recyclerView) {
        Log.d(TAG, "onAttachedToWindow");
        super.onAttachedToWindow(recyclerView);
        mRecyclerView = recyclerView;
        mRecyclerView.addOnItemTouchListener(new ThresholdDetector());
    }

    private final class ThresholdDetector implements RecyclerView.OnItemTouchListener {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent e) {
            // some calculations
            return true;
        }

        @Override
        public void onTouchEvent(final RecyclerView view, final MotionEvent e) {
            final int action = e.getActionMasked();
            mVelocityTracker.addMovement(e);
            if(action == MotionEvent.ACTION_MOVE) {
                if (thresholdMet) {
                    // Custom scroll
                    mRecyclerView.scrollBy(calculatedAmount)
                } else {
                    // Scroll normally as per Android LinearLayoutManager
                }
            }
        }
    }
}

如果不满足阈值,我需要Android来处理滚动,否则我无法平滑滚动。我在 else 中尝试了以下操作(当不满足阈值时),但它并不完全有效。

                    mRecyclerView.post(new Runnable() {
                        @Override
                        public void run() {
                            mRecyclerView.smoothScrollBy(-(int)getDeltaX(motionEvent), 0);
                        }
                    });

标签: androidandroid-recyclerviewontouchlistenerontouch

解决方案


如果没有看到整个ThresholdDetector课程,就不可能确定最好的解决方案是什么。也就是说,我相信问题在于您总是trueonInterceptTouchEvent().

在返回值的文档中onInterceptTouchEvent()

返回:true如果它OnItemTouchListener希望开始拦截触摸事件,false则继续当前行为并继续观察手势中的未来事件。

在描述中onTouchEvent()

将触摸事件作为手势的一部分处理,该手势通过true从先前的调用返回来声明onInterceptTouchEvent()

换句话说,onTouchEvent()只会在您trueonInterceptTouchEvent(). 如果您希望 RecyclerView 执行其默认行为,只需在滚动速度低于您的阈值时返回falseonInterceptTouchEvent()


推荐阅读