我有一个 View
,它有一些垂直手势
,例如向下滑动以向下移动 View
等。我们将此 View 称为 Root View
。一切都很好,但我需要在其上添加一个 View 寻呼机。现在,ViewPager
正在消耗所有触摸事件。 ViewPager 按其应有的方式水平滚动,但也消耗垂直滑动并且不执行任何操作(不将事件传递给 rootView)。如何让两个 View 监听其相应的触摸事件并将其余的发送给其他 View 。我尝试创建一个 CustomViewPager 并重写其 onTouchEvent
,希望首先识别向下滑动并在这种情况下 return false
,以便 rootview 有机会处理该触摸事件。但在识别手势为 down/up 的过程中,ViewPager
正在消耗 ACTION_DOWN
和 ACTION_MOVE
事件,这是 所需的rootView
处理手指移动量。
我想到的一个解决方案是在 ViewPager
上的所有 layout
上添加 onTouchEvent
,它可以识别 Vertical
与 horizontal
并调用适当的 touchevent(rootView
与 ViewPager
),但为了识别上/下/侧手势时,layout
将消耗一些可能对 rootView
有值(value)的事件。
想到的另一个解决方案是覆盖ViewPager
的ontouchEvent
并调用rootView的onTouchEvent
,无论向上/向下/侧向运动。这样 ViewPager
和 rootView
都可以使用该事件,但有时会导致屏幕波动。
我该如何解决这个问题?我希望得到一些建议,不需要提供代码,只是解决这个问题的好方法。
最佳答案
我必须完全修改我原来的答案。我的第一个解决方案是子类化 ViewPager 并覆盖 onTouchEvent()
,添加在 CustomViewPager
和其下面的 RelativeLayout
之间切换的逻辑。返回 false 意味着 View 忽略该事件,返回 super.onTouchEvent(event) 意味着 View 消耗该事件直到用户抬起手指。所有逻辑都在事件的 ACTION_MOVE
部分,但由于您只有一次返回值的机会(这是事件的第一部分,ACTION_DOWN
),您不能使用任何移动来确定是消耗还是忽略该事件。
我最终通过编写一个全新的类来使其工作,从 ViewPager
代码开始,并添加逻辑来识别垂直手势。当发生垂直手势时,将运行作用于其下方的 RelativeLayout
的代码,而不是将触摸事件传递给它。下面是我的类的 onTouchEvent()
中的代码 fragment 。
public class CustomViewPager extends ViewGroup {
// code from ViewPager class...
case MotionEvent.ACTION_MOVE:
if (!mIsBeingDragged) {
if (DEBUG) Log.v(TAG, "!mIsBeingDragged");
final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, pointerIndex);
final float xDiff = Math.abs(x - mLastMotionX);
final float y = MotionEventCompat.getY(ev, pointerIndex);
final float yDiff = Math.abs(y - mLastMotionY);
if (DEBUG) Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff);
if (xDiff > mTouchSlop && xDiff > yDiff) {
isVerticalMovement = false;
hasMovedHorizontally = true;
if (DEBUG) Log.v(TAG, "Starting drag!");
mIsBeingDragged = true;
requestParentDisallowInterceptTouchEvent(true);
mLastMotionX = x - mInitialMotionX > 0 ? mInitialMotionX + mTouchSlop :
mInitialMotionX - mTouchSlop;
mLastMotionY = y;
setScrollState(SCROLL_STATE_DRAGGING);
setScrollingCacheEnabled(true);
// Disallow Parent Intercept, just in case
ViewParent parent = getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
}
else {
if (yDiff > mTouchSlop) {
// VERTICAL SWIPE -- do stuff here...
}
}
}
}
关于android - 如何检测 View 寻呼机垂直滑动并将该事件发送到下面的布局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30466744/