使用LinearLayoutManager正常滚动实现OnItemTouchListener的RecyclerView

时间:2019-09-15 17:24:15

标签: android android-recyclerview ontouchlistener ontouch

我正在尝试实现一个用例,当用户以较低的速度滚动时,我需要正常滚动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处理滚动,否则无法平滑滚动。我在其他情况下(未达到阈值时)尝试了以下方法,但效果不佳。

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

1 个答案:

答案 0 :(得分:1)

没有看到ThresholdDetector类的全部,就不可能确定到底什么是最好的解决方案。也就是说,我相信问题是您总是从true返回onInterceptTouchEvent()

在文档中有关onInterceptTouchEvent()的返回值:

  

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

onTouchEvent()的说明中:

  

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

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