如何将click事件传递给RecyclerView的项目?

时间:2018-02-14 06:44:23

标签: android android-recyclerview touch ontouchlistener motionevent

我有一个普通的RecyclerView,并且在其上面有一个实现View的透明GestureListener,它基本上具有RecyclerView的相同大小。

GestureListener会听取滚动和拖动手势,并将此MotionEvent传递给它下面的RecyclerView

我已经让RecyclerView能够滚动和投掷。但是,我无法找到将点击事件传递到RecyclerView的方法。

我已经知道这是因为ACTION_DOWN中消耗了GestureListener。事实上,GestureListener有一个onSingleTap()方法供您覆盖,每当我执行点击时都会调用此方法。

根据this post,我尝试将OnTouchListener设置为我的itemView并收听ACTION_UP个事件。但是,永远不会调用onTouch()方法。

以下是我的表现方式:
1.在透明的GestureListener

中创建一个回调
   @Override
    public boolean onSingleTapUp(MotionEvent e) {
        if (scrollDetector == null) return false;
        scrollDetector.onSingleTap(e);
        return true;
    }
  1. 在活动中配置回调,并将MotionEvent传递给RecyclerView

    @Override
    public void onSingleTap(MotionEvent e) {
        mRecyclerView.onTouchEvent(e);
    }
    
  2. OnTouchListener设置为适配器中的itemView:

    itemView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                v.performClick();
                return true;
            }
            return false;
        }
    });
    
  3. 使用调试器,我可以看到mRecyclerView.onTouchEvent(e)被调用;但是没有调用itemView的onTouch()

    那么......我应该如何正确地将MotionEvent传递给itemView?

    您可能会问 - "为什么要在RecyclerView上放置GestureListener?"
    这是因为我需要在滚动RecyclerView时更改RecyclerView的高度。但是,如果我使用RecyclerView' addOnScrollListener执行此操作,dy的值将在负值和正值之间波动,因为dy也会受到其高度的影响。并且波动也将反映到用户界面 因此,我需要一个滚动检测器,滚动时不会改变其高度,只需通过编程调用RecyclerViewscrollBy()将滚动和拖动值传递给fling()

2 个答案:

答案 0 :(得分:0)

你应该知道recyclerview的事件。如果你在滚动视图时可以移动recyclelerview,它会调用onInterceptTouchEvent()并返回true来拦截event.So你无法获得ACTION_MOVE事件。也许你应该重写recyclelerview的onInterceptTouchEvent( )并返回false。然后,您可以在itemView的方法中获取所有事件。

答案 1 :(得分:0)

愚蠢的我。我应该使用dispatchTouchEvent(MotionEvent e)代替onTouchEvent(MotionEvent e)

但是,这还不够 简单地使用GestureListener中的MotionEvent调用dispatchTouchEvent(e)不起作用,因为eACTION_UP事件。

要模拟点击,您需要ACTION_DOWNACTION_UP

并且itemView不需要设置OnTouchListener,因为您已经模拟了

代码:

        @Override
        public void onSingleTap(MotionEvent e) {
            long downTime = SystemClock.uptimeMillis();
            long upTime = downTime + 100;
            MotionEvent downEvent = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_DOWN,
                    e.getX(), e.getY(), 0);
            mRecyclerView.dispatchTouchEvent(downEvent);
            MotionEvent upEvent = MotionEvent.obtain(upTime, upTime, MotionEvent.ACTION_UP,
                    e.getX(), e.getY(), 0);
            mRecyclerView.dispatchTouchEvent(upEvent);
            downEvent.recycle();
            upEvent.recycle();
        }