横向的scrollView 中,是一个横向的recyclerView A, recyclerView A的item是竖向的recyclerViewB, 如何让scrollView 以及 recyclerView处理两根手指的滑动事件
时间: 2023-11-16 22:00:55 浏览: 132
实现ScrollView和RecyclerView的多指手势处理可以通过继承ScrollView和RecyclerView来实现。
首先,我们需要自定义一个类来继承ScrollView,并重写onInterceptTouchEvent()和onTouchEvent()方法。在onInterceptTouchEvent()方法中判断是否有多指触摸事件,并返回true,拦截ScrollView的触摸事件。在onTouchEvent()方法中判断是否有多指触摸事件,并将事件分发给子View处理。
代码示例:
```
public class MultiGestureScrollView extends ScrollView {
private int mActivePointerId = -1;
private int mLastMotionX;
private int mLastMotionY;
public MultiGestureScrollView(Context context) {
super(context);
}
public MultiGestureScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MultiGestureScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
mActivePointerId = ev.getPointerId(0);
mLastMotionX = (int) ev.getX();
mLastMotionY = (int) ev.getY();
} else if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
return true;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = ev.getPointerId(0);
mLastMotionX = (int) ev.getX();
mLastMotionY = (int) ev.getY();
break;
case MotionEvent.ACTION_POINTER_DOWN:
return true;
case MotionEvent.ACTION_MOVE:
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
final int x = (int) ev.getX(activePointerIndex);
final int y = (int) ev.getY(activePointerIndex);
final int deltaX = mLastMotionX - x;
final int deltaY = mLastMotionY - y;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
// 横向滑动
getParent().requestDisallowInterceptTouchEvent(true);
super.onTouchEvent(ev);
return true;
} else {
// 竖向滑动
getParent().requestDisallowInterceptTouchEvent(false);
return super.onTouchEvent(ev);
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mActivePointerId = -1;
break;
}
return super.onTouchEvent(ev);
}
}
```
接下来,我们需要自定义一个类来继承RecyclerView,并重写onInterceptTouchEvent()和onTouchEvent()方法,实现多指手势处理。在onInterceptTouchEvent()方法中判断是否有多指触摸事件,并返回true,拦截RecyclerView的触摸事件。在onTouchEvent()方法中判断是否有多指触摸事件,并将事件分发给子View处理。
代码示例:
```
public class MultiGestureRecyclerView extends RecyclerView {
private int mActivePointerId = -1;
private int mLastMotionX;
private int mLastMotionY;
public MultiGestureRecyclerView(Context context) {
super(context);
}
public MultiGestureRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MultiGestureRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
mActivePointerId = ev.getPointerId(0);
mLastMotionX = (int) ev.getX();
mLastMotionY = (int) ev.getY();
} else if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
return true;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = ev.getPointerId(0);
mLastMotionX = (int) ev.getX();
mLastMotionY = (int) ev.getY();
break;
case MotionEvent.ACTION_POINTER_DOWN:
return true;
case MotionEvent.ACTION_MOVE:
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
final int x = (int) ev.getX(activePointerIndex);
final int y = (int) ev.getY(activePointerIndex);
final int deltaX = mLastMotionX - x;
final int deltaY = mLastMotionY - y;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
// 横向滑动
getParent().requestDisallowInterceptTouchEvent(true);
super.onTouchEvent(ev);
return true;
} else {
// 竖向滑动
getParent().requestDisallowInterceptTouchEvent(false);
return super.onTouchEvent(ev);
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mActivePointerId = -1;
break;
}
return super.onTouchEvent(ev);
}
}
```
最后,我们将自定义的MultiGestureRecyclerView作为横向的RecyclerView A的布局管理器,并将MultiGestureScrollView包裹横向的RecyclerView A。
代码示例:
```
<com.example.MultiGestureScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:recycledViewPool="@{recycledViewPool}"
tools:listitem="@layout/item_horizontal_recycler_view">
<com.example.MultiGestureRecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:recycledViewPool="@{recycledViewPool}"
tools:listitem="@layout/item_vertical_recycler_view"/>
</androidx.recyclerview.widget.RecyclerView>
</com.example.MultiGestureScrollView>
```
阅读全文