增加Android按钮中的触摸斜率
我们有一个安卓应用程序,安装在崎岖地形下行驶的车辆仪表板上,所以一切都很不稳定。我们发现,在这种情况下,在屏幕上进行一次点击是困难的,因为点击通常被解释为小阻力 我需要的是在手指出现之前有一点晃动的触摸事件被解释为点击,而不是拖动。我一直在阅读安卓系统中触摸屏的工作方式,我可以看到他们已经解释了这一点。我真正需要了解的是,如何为Android增加Android按钮中的触摸斜率,android,button,touch-event,Android,Button,Touch Event,我们有一个安卓应用程序,安装在崎岖地形下行驶的车辆仪表板上,所以一切都很不稳定。我们发现,在这种情况下,在屏幕上进行一次点击是困难的,因为点击通常被解释为小阻力 我需要的是在手指出现之前有一点晃动的触摸事件被解释为点击,而不是拖动。我一直在阅读安卓系统中触摸屏的工作方式,我可以看到他们已经解释了这一点。我真正需要了解的是,如何为Android按钮小部件的子类增加“touch slop” 仅仅几行代码就可以做到这一点吗?或者我需要自己实现onInterceptTouchEvent和“onTouch
按钮
小部件的子类增加“touch slop”
仅仅几行代码就可以做到这一点吗?或者我需要自己实现
onInterceptTouchEvent
和“onTouchEvent”吗?如果是后者,谁能给我一些关于如何工作的指导吗?以下是我所做的,希望能对你们有所帮助
private Rect mBtnRect;
yourView.setOnTouchListener(new OnTouchListener() {
private boolean isCancelled = false;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isCancelled = false;
parent.requestDisallowInterceptTouchEvent(true); // prevent parent and its ancestors to intercept touch events
createClickArea(v);
// your logic touch down
return true;
case MotionEvent.ACTION_UP:
if(!isCancelled) {
// Click logic
}
// release mBtnRect when cancel or up event
mBtnRect = null;
return true;
case MotionEvent.ACTION_CANCEL:
isCancelled = true;
releaseTouch(parent, v);
return true;
case MotionEvent.ACTION_MOVE:
if(!isBelongTouchArea(event.getRawX(), event.getRawY())) {
isCancelled = true;
releaseTouch(parent, v);
}
return true;
default:
break;
}
}
// Create the area from the view that user is touching
private final void createClickArea(View v) {
// for increase rect area of button, pixel in used.
final int delta = (int) mContext.getResources().getDimension(R.dimen.extension_area);
final int[] location = new int[2];
// Get the location of button call on screen
v.getLocationOnScreen(location);
// Create the rect area with an extension defined distance.
mBtnRect = new Rect(v.getLeft() - delta, location[1] + v.getTop() - delta, v.getRight(), location[1] + v.getBottom() + delta);
}
//Check the area that contains the moved position or not.
private final boolean isBelongTouchArea(float rawX, float rawY) {
if(mBtnRect != null && mBtnRect.contains((int)rawX, (int)rawY)) {
return true;
}
return false;
}
private void releaseTouch(final ListView parent, View v) {
parent.requestDisallowInterceptTouchEvent(false);
mBtnRect = null;
// your logic
}
对于我们使用android.opengl.GLSURFACHEVIEW的简单用例,我们解决了与您相同的问题,我们说,“如果手势中移动的距离小于某个阈值,请将其解释为单击”。我们使用了两个2D点之间的标准欧几里德距离=
sqrt((deltaX)^2+(deltaY)^2))
,其中deltaX
和deltaY
是用户运动姿态中移动距离的X和Y分量
更准确地说,让(x1,y1)
成为用户手势“开始”的坐标,让(x2,y2)
成为手势“结束”的坐标
然后,deltaX=x2-x1
(或者它也可以是x1-x2
,但符号与距离cz无关,我们将值平方),同样,对于deltaY
根据这些增量,我们计算欧几里德距离,如果它小于阈值,用户可能希望它是一个点击,但由于设备的触摸斜率,它被归类为移动手势,而不是点击
在实现方面,是的,我们超越了android.view.view#onTouchEvent(MotionEvent)和
- 录制的
当屏蔽动作为(x1,y1)
或android.view.MotionEvent#action#POINTER_DOWN
android.view.MotionEvent#action#DOWN
- 当屏蔽动作是android.view.MotionEvent#action_MOVE时,
可以从事件的(x2,y2)
和getX
方法获得(请参阅)getY