我有一个普通的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;
}
在活动中配置回调,并将MotionEvent
传递给RecyclerView
@Override
public void onSingleTap(MotionEvent e) {
mRecyclerView.onTouchEvent(e);
}
将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;
}
});
使用调试器,我可以看到mRecyclerView.onTouchEvent(e)
被调用;但是没有调用itemView的onTouch()
。
那么......我应该如何正确地将MotionEvent
传递给itemView?
您可能会问 - "为什么要在RecyclerView上放置GestureListener?"
这是因为我需要在滚动RecyclerView
时更改RecyclerView
的高度。但是,如果我使用RecyclerView
' addOnScrollListener
执行此操作,dy
的值将在负值和正值之间波动,因为dy也会受到其高度的影响。并且波动也将反映到用户界面
因此,我需要一个滚动检测器,滚动时不会改变其高度,只需通过编程调用RecyclerView
和scrollBy()
将滚动和拖动值传递给fling()
。
答案 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)
不起作用,因为e
是ACTION_UP
事件。
要模拟点击,您需要ACTION_DOWN
和ACTION_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();
}