如果您已经有一个回收器触摸侦听器并且想要处理其中的所有触摸事件而不是在视图持有者中单独处理按钮触摸事件,则只想添加另一个解决方案。这个类的改编版本所做的关键是在点击时返回 onItemClick() 回调中的按钮视图,而不是项目容器。然后,您可以测试视图是否为按钮,并执行不同的操作。请注意,长按按钮仍被解释为长按整行。
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener
{
public static interface OnItemClickListener
{
public void onItemClick(View view, int position);
public void onItemLongClick(View view, int position);
}
private OnItemClickListener mListener;
private GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener)
{
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener()
{
@Override
public boolean onSingleTapUp(MotionEvent e)
{
// Important: x and y are translated coordinates here
final ViewGroup childViewGroup = (ViewGroup) recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childViewGroup != null && mListener != null) {
final List<View> viewHierarchy = new ArrayList<View>();
// Important: x and y are raw screen coordinates here
getViewHierarchyUnderChild(childViewGroup, e.getRawX(), e.getRawY(), viewHierarchy);
View touchedView = childViewGroup;
if (viewHierarchy.size() > 0) {
touchedView = viewHierarchy.get(0);
}
mListener.onItemClick(touchedView, recyclerView.getChildPosition(childViewGroup));
return true;
}
return false;
}
@Override
public void onLongPress(MotionEvent e)
{
View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
if(childView != null && mListener != null)
{
mListener.onItemLongClick(childView, recyclerView.getChildPosition(childView));
}
}
});
}
public void getViewHierarchyUnderChild(ViewGroup root, float x, float y, List<View> viewHierarchy) {
int[] location = new int[2];
final int childCount = root.getChildCount();
for (int i = 0; i < childCount; ++i) {
final View child = root.getChildAt(i);
child.getLocationOnScreen(location);
final int childLeft = location[0], childRight = childLeft + child.getWidth();
final int childTop = location[1], childBottom = childTop + child.getHeight();
if (child.isShown() && x >= childLeft && x <= childRight && y >= childTop && y <= childBottom) {
viewHierarchy.add(0, child);
}
if (child instanceof ViewGroup) {
getViewHierarchyUnderChild((ViewGroup) child, x, y, viewHierarchy);
}
}
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e)
{
mGestureDetector.onTouchEvent(e);
return false;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent){}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
然后从活动/片段中使用它:
recyclerView.addOnItemTouchListener(createItemClickListener(recyclerView));
public RecyclerItemClickListener createItemClickListener(final RecyclerView recyclerView) {
return new RecyclerItemClickListener (context, recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
if (view instanceof AppCompatButton) {
// ... tapped on the button, so go do something
} else {
// ... tapped on the item container (row), so do something different
}
}
@Override
public void onItemLongClick(View view, int position) {
}
});
}