RecyclerView 实现 OnItemTouchListener with LinearLayoutManager 正常滚动

RecyclerView that implements OnItemTouchListener with LinearLayoutManager scrolling normally

我正在尝试实现一个用例,当用户以低速滚动时,我需要正常滚动 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);
                        }
                    });

如果不完整地查看 ThresholdDetector class,就无法确定最佳解决方案是什么。也就是说,我认为问题在于您总是从 onInterceptTouchEvent().

returning true

onInterceptTouchEvent() 的 return 值的文档中:

Returns: true if this OnItemTouchListener wishes to begin intercepting touch events, false to continue with the current behavior and continue observing future events in the gesture.

并且在 onTouchEvent() 的描述中:

Process a touch event as part of a gesture that was claimed by returning true from a previous call to onInterceptTouchEvent().

换句话说,只有当您 return true 来自 onInterceptTouchEvent() 的给定事件时,才会调用 onTouchEvent()。如果您希望 RecyclerView 执行其默认行为,只需 return false from onInterceptTouchEvent() 当滚动速度低于您的阈值时。