【发布时间】:2018-02-10 11:40:58
【问题描述】:
我有一个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;
}
}
【问题讨论】: