Com*_*02x 6 android ontouchlistener motionevent
我有这个问题ACTION_CANCEL没有被触发,我已经在我的其他项目中实现了它并且工作正常.似乎ACTION_UP是唯一MotionEvent被称之为的ACTION_DOWN.ACTION_CANCEL一旦我的手指不再在视野中或屏幕外,我想触发.
示例场景:我点击视图,这是一个LinearLayout btw,在ACTION_DOWN其背景上更改为图像的"单击/暗淡"版本,并且当ACTION_UP触发时,只有当手指在LinearLayout内时,其背景才会变回默认图像.现在的问题是,当我按下它并将手指放在屏幕上,并将我的手指拖到LinearLayout之外时,ACTION_UP仍然会触发它应该没有的位置.
这是我的代码:
dimView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(final View view,
final MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
Log.d("TAG", "DOWN");
return true;
} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
Log.d("TAG", "UP");
return true;
} else if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {
Log.d("TAG", "CANCEL");
return true;
}
return false;
}
});
Run Code Online (Sandbox Code Playgroud)
其中:dimView是一个LinearLayout
Tos*_*she 14
我已经调试了这个很长一段时间了,因为它非常随机地出现了很多困扰我.然后我在不同设备上测试了我的代码,并意识到Android实现了API实现的变化.Android 4.1.2(在Galaxy Tab 2上测试)的预期行为和代码工作得非常好,但是您描述的错误可以在Nexus 7(Android 4.2)上看到.显然,Android改变了在API 17中处理MotionEvent的方式.
没有发生错误的一个特殊情况是视图位于a GroupLayout下面ScrollView.当可以滚动时,ACTION_CANCEL会被触发.但是,如果无法滚动,则错误仍然存在.
起初我尝试组合一个OnClickListener,OnTouchListener以便最后一个只能处理动画,但无济于事.从父母调度事件也不起作用.
一个解决办法是捕捉ACTION_MOVE事件和检查手指位于使用视图的边界之外v.getX(),并v.getY()与他们进行比较event.getX()和event.getY()体面.全局布尔变量(isOutside)可用于存储最新信息.在启动之前,ACTION_UP您可以检查最新状态isOutside并相应地执行动画和操作.您还可以返回true或false,具体取决于您是否捕获了事件.
更新:在这里挖了一下之后我发现了这个解决方案: Android:检测用户是否触摸并拖出按钮区域?并编译了这段代码.这个想法是相同的,除了它创建一个矩形并检查事件边界是否在视图的矩形内.
someView.setOnTouchListener(new View.OnTouchListener() {
private Rect rect;
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d(TAG,"Touched: "+event.getAction());
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.d(TAG,"ACTION_DOWN");
animateImageButtonOnClick(v, event);
rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
}
if (event.getAction() == MotionEvent.ACTION_UP) {
Log.d(TAG,"ACTION_UP");
if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) {
Log.d(TAG,"ACTION_UP - outside");
animateImageButtonOnRelease(v, event);
} else {
Log.d(TAG,"ACTION_UP - inside");
// do your stuff here
}
}
if(event.getAction() == MotionEvent.ACTION_MOVE){
if(!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())){
animateImageButtonOnReleaseWithLowDuration(v, event);
}
}
if (event.getAction() == MotionEvent.ACTION_CANCEL){
Log.d(TAG,"ACTION_CANCEL");
animateImageButtonOnRelease(v, event);
return true;
}
return true;
}
});
Run Code Online (Sandbox Code Playgroud)
小智 -1
Override dispatchTouchEvent method maybe deal with it;
Run Code Online (Sandbox Code Playgroud)
dimView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
// to call super touch method
return false;
}
});
@Override
public boolean dispatchTouchEvent(MotionEvent motionEvent) {
// TODO Auto-generated method stub
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
Log.d("TAG", "DOWN");
return true;
} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
Log.d("TAG", "UP");
return true;
} else if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {
Log.d("TAG", "CANCEL");
return true;
}
return super.dispatchTouchEvent(motionEvent);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3793 次 |
| 最近记录: |