ScrollView 中的 View 中的 OnTouchListener
OnTouchListener in View that is inside ScrollView
我在 ScrollView
中有一个视图。只要用户按住该视图,我想每 80 毫秒调用一次方法。这是我实现的:
final Runnable vibrate = new Runnable() {
public void run() {
vibrate();
}
};
theView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
final ScheduledFuture<?> vibrateHandle =
scheduler.scheduleAtFixedRate(vibrate, 0, 80, MILLISECONDS);
vibrateHanlers.add(vibrateHandle);
return true;
}
if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL
|| motionEvent.getAction() == MotionEvent.ACTION_UP) {
clearAllScheduledFutures();
return false;
}
return true;
}
});
问题是,ACTION_CANCEL
是为手指的最小移动而调用的。我知道那是因为 View
在 ScrollView
里面,但我不确定我在这里有什么选择。我是否创建自定义 ScrollView
,并尝试查找是否触摸了所需的视图并禁用 ScrollView
的触摸事件?或者,为小的移动阈值禁用 SrollView
的触摸事件?或者别的什么?
您能否尝试在 ActionUp 事件中 return true 而不是 false,这样该事件被视为已消耗
if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL
|| motionEvent.getAction() == MotionEvent.ACTION_UP) {
clearAllScheduledFutures();
return true;
}
这是我修复它的方法。
我创建了自定义 ScrollView
:
public class MainScrollView extends ScrollView {
private boolean shouldStopInterceptingTouchEvent = false;
public void setShouldStopInterceptingTouchEvent(boolean shouldStopInterceptingTouchEvent) {
this.shouldStopInterceptingTouchEvent = shouldStopInterceptingTouchEvent;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (shouldStopInterceptingTouchEvent)
return false;
else
return super.onInterceptTouchEvent(ev);
}
}
并且在 onTouchEvent 中:
theView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
svMain.setShouldStopInterceptingTouchEvent(true);
final ScheduledFuture<?> vibrateHandle =
scheduler.scheduleAtFixedRate(vibrate, 0, 80, MILLISECONDS);
vibrateHanlers.add(vibrateHandle);
return true;
}
if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL
|| motionEvent.getAction() == MotionEvent.ACTION_UP) {
svMain.setShouldStopInterceptingTouchEvent(false);
clearAllScheduledFutures();
return false;
}
return true;
}
});
所以,我决定在 View
的 onTouchListener
中决定何时停止拦截 touchEvent
。
我在 ScrollView
中有一个视图。只要用户按住该视图,我想每 80 毫秒调用一次方法。这是我实现的:
final Runnable vibrate = new Runnable() {
public void run() {
vibrate();
}
};
theView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
final ScheduledFuture<?> vibrateHandle =
scheduler.scheduleAtFixedRate(vibrate, 0, 80, MILLISECONDS);
vibrateHanlers.add(vibrateHandle);
return true;
}
if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL
|| motionEvent.getAction() == MotionEvent.ACTION_UP) {
clearAllScheduledFutures();
return false;
}
return true;
}
});
问题是,ACTION_CANCEL
是为手指的最小移动而调用的。我知道那是因为 View
在 ScrollView
里面,但我不确定我在这里有什么选择。我是否创建自定义 ScrollView
,并尝试查找是否触摸了所需的视图并禁用 ScrollView
的触摸事件?或者,为小的移动阈值禁用 SrollView
的触摸事件?或者别的什么?
您能否尝试在 ActionUp 事件中 return true 而不是 false,这样该事件被视为已消耗
if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL
|| motionEvent.getAction() == MotionEvent.ACTION_UP) {
clearAllScheduledFutures();
return true;
}
这是我修复它的方法。
我创建了自定义 ScrollView
:
public class MainScrollView extends ScrollView {
private boolean shouldStopInterceptingTouchEvent = false;
public void setShouldStopInterceptingTouchEvent(boolean shouldStopInterceptingTouchEvent) {
this.shouldStopInterceptingTouchEvent = shouldStopInterceptingTouchEvent;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (shouldStopInterceptingTouchEvent)
return false;
else
return super.onInterceptTouchEvent(ev);
}
}
并且在 onTouchEvent 中:
theView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
svMain.setShouldStopInterceptingTouchEvent(true);
final ScheduledFuture<?> vibrateHandle =
scheduler.scheduleAtFixedRate(vibrate, 0, 80, MILLISECONDS);
vibrateHanlers.add(vibrateHandle);
return true;
}
if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL
|| motionEvent.getAction() == MotionEvent.ACTION_UP) {
svMain.setShouldStopInterceptingTouchEvent(false);
clearAllScheduledFutures();
return false;
}
return true;
}
});
所以,我决定在 View
的 onTouchListener
中决定何时停止拦截 touchEvent
。