我有一个RelativeLayout
,其中包含许多具有各种触摸事件的子视图。我想在用户滑动父RelativeLayout
的任何位置时收到通知,这样我就可以更新一些UI,同时让子视图处理他们自己的触摸/拖动事件。为Android完成此操作的标准方法是什么?
我在想我可以在所有视图上叠加并让它检测滑动手势,如果没有滑动,我可以将触摸事件传递给层次结构中的其他视图。看起来Android似乎不支持那种触摸检测,一旦一个视图决定查看事件是否是某个手势,其他任何视图都无法看到这些事件。
滑动手势包含三个触摸事件:ACTION_DOWN,ACTION_MOVE和ACTION_UP。您需要记录所有三个事件,然后查看它是否是滑动。如果它不是滑动,那么我们需要将这些事件传递给其他子视图,以查看它是否符合他们正在寻找的手势的标准。如果是滑动,我们会阻止将事件发送到子视图。只是不确定这是否真的可行。
更新
在答案部分使用用户的想法,我能够编写符合我的规范的布局。此RelativeLayout
只处理左右滑动,但可以添加以处理更多方向。 OnSwipeListener
只是一个interface
,有两种方法void swipedLeft()
和void swipedRight()
。
public class SwipeRelativeLayout extends RelativeLayout {
public OnSwipeListener mSwipeListener = null;
private static final int SWIPE_DISTANCE_THRESHOLD = 100;
private float mStartX = 0;
private float mStartY = 0;
private float mEndX = 0;
private float mEndY = 0;
public SwipeRelativeLayout(Context context) {
super(context);
}
public SwipeRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SwipeRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public SwipeRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean handled = onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) return handled;
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
mStartX = event.getRawX();
mStartY = event.getRawY();
break;
}
case MotionEvent.ACTION_MOVE: {
float distanceX = event.getRawX() - mStartX;
float distanceY = event.getRawY() - mStartY;
if (Math.abs(distanceX) > Math.abs(distanceY) && Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD) {
if (distanceX > 0) {
if (mSwipeListener != null) mSwipeListener.swipedRight();
} else {
if (mSwipeListener != null) mSwipeListener.swipedLeft();
}
return true;
}
return false;
}
}
return true;
}
}
答案 0 :(得分:2)
当触摸事件发生时,它首先被传递到父布局视图,并通过onInterceptTouchEvent
传递给子视图,返回true或false。您希望覆盖并拦截父RelativeLayout
上的触摸事件,并确定您是否看过滑动手势。如果您已经看过想要返回的滑动,那么您已经处理了它。在这种情况下,ACTION_UP
是可能滑动的结束,如果您的onTouchEvent
处理了该事件,那么您可以返回true并且其下方的视图将无法获得整理事件,从而忽略其手势。
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean handled = onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) return handled;
return false;
}