我有一个需要以不寻常的方式处理事件的应用程序。
对于我的问题,让我首先解释一个简单的案例,即Android的当前事件处理系统不适合我。
假设我有一个FrameLayout(我现在称之为ViewSwiper),其上添加的所有Views都是MATCH_PARENT X MATCH_PARENT(我称之为PageView),它通过翻译实际的View来处理事件并替换它在移动的方向。 我已经完成并正常工作的这个组件(Using Animation to swipe views)。
但问题在于我在其上添加的PageView,如果ImageViews在onTouchEvent上返回false,ViewSwiper将处理事件并让另一个PageView进入屏幕,但如果我在其上添加ScrollView ,所有事件都将由Scroll使用,ViewSwiper将无法替换PageView。
所以我想通过返回ScrollView的假onTouchEvent,父可以假设它的事件,我编写了ScrollView的这个子类来测试它:
public class ScrollViewVertical extends ScrollView {
public ScrollViewVertical(Context context) {
super(context);
setOverScrollMode(OVER_SCROLL_ALWAYS);
setVerticalScrollBarEnabled(false);
}
public boolean onTouchEvent(MotionEvent evt) {
super.onTouchEvent(evt);
return false;
}
}
但返回false会使任何其他事件被调度到父级,但是我需要这些事件进行VERTICAL滚动,所以我只想在用户移动HORIZONTAL时返回falses,这就是我的代码: / p>
public class ScrollViewVertical extends ScrollView {
private MovementTracker moveTracker;
public ScrollViewVertical(Context context) {
super(context);
setOverScrollMode(OVER_SCROLL_ALWAYS);
setVerticalScrollBarEnabled(false);
moveTracker = new MovementTracker();
}
public boolean onTouchEvent(MotionEvent evt) {
if (moveTracker.track(evt))
if (moveTracker.getDirection() == Direction.HORIZONTAL)
return false;
return super.onTouchEvent(evt);
}
}
PS:在一些事件发生后,MovementTracker将在track()上返回true,并告诉用户移动的方向。
但在这种情况下,ScrollView会继续接收事件,因为它在第一个事件中返回true。
有关如何处理ViewSwiper上的事件的任何想法,当它的子节点返回false时(即使返回了一些真值)。
PS:如果需要,我可以提供更多相关信息,并接受不同的解决方案。
根据答案,我尝试了以下内容:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
onTouchEvent(ev);
return intercept;
}
public boolean onTouchEvent(MotionEvent evt) {
boolean x = super.onTouchEvent(evt);
if (moveTracker.track(evt)) {
intercept = moveTracker.getDirection() != Direction.VERTICAL;
if (!intercept)
getParent().requestDisallowInterceptTouchEvent(false);
}
return x;
}
仍然没有。
答案 0 :(得分:3)
在scrollview的onTouchEvent()
中尝试此操作
//if (evt.getAction() == MotionEvent.ACTION_MOVE) {
if (moveTracker.track(evt)){
if (moveTracker.getDirection() == Direction.VERTICAL){
//Or the direction you want the scrollview keep moving
getParent().requestDisallowInterceptTouchEvent(true);
}
}
return true;
更新
请尝试以下自定义Scrollview
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
super.dispatchTouchEvent(ev);
return false;
}
没有别的
这种方式我假设MotionEvent将在两个视图上执行。而且由于它们没有冲突(一个是垂直的,另一个是水平的)这可以起作用
答案 1 :(得分:1)
根据weakwire的回答,我找到了以下解决方案:
在ViewSwiper上
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if(!super.dispatchTouchEvent(ev))
onTouchEvent(ev);
return true;
}
在ScrollHorizontal上,当我不再需要时,我会在dispatchTouchEvent上返回false。