我在互联网上找到了一个很好的监听器类来制作一个OnSwipeTouchListener。该监听器可以确定用户何时向下,向上,向左或向右滑动:
std::function<void(int&)>
这就是我使用它的方式:
std::function<void(int&)> myFunction = [](int& x) { ++x; };
foo(myFunction);
现在,我想添加函数onSwipeL()。此功能是当用户用手指制作字母L时,就像onSwipeDown()+ onSwipeRight()。
最好的方法是使用onSwipeDoubleL()函数。这是当用户用手指翻转双L时。它就像制作一样:
这可能吗?
答案 0 :(得分:0)
有两种选择。
N
为真,请检查onSwipeRight()
,如果是,则执行操作。在isSwipedDown
中将布尔值设置为true,在所有其他值(不包括向下)中设置为false。答案 1 :(得分:0)
我真的无法理解为什么你需要这个姿势。但这是我的解决方案。我们应该捕获触摸事件,因此覆盖onTouchEvent方法。我们需要在屏幕上阅读手指索引。
如果我们有多个触摸应用右手指数,其中X坐标超过&#34;左手指&#34;。如果找到正确的索引,我无法说出来。所以我检查索引坐标。
在下一步中,我们保存起点并开始向下移动。如果我们在屏幕上有两个手指,则只检查左右手指(或者你想要的右手)。
如果我们在&#34; down&#34;距离大于最小值,我们开始向左/右移动,我们需要保存新的起点以便从中计算距离。
等待用户向左/向右移动距离超过分钟。毕竟通过&#34; left&#34;检查成功和&#34;对&#34;手指或刚刚离开(一触)。
我们还需要考虑移动时的不准确性(错误,错误)。用户无法向下移动或完全正确,因此解决方案高度依赖于此参数。您必须平衡范围和精度参数以舒适手势控制。
代码未优化仅显示基本思路。也许你会找到更多的小解决方案。对不起我的英语水平
public class MainMenuActivity extends AppCompatActivity {
boolean movingDownL = false;
boolean movingDownR = false;
boolean movingLeft = false;
boolean movingRight = false;
boolean movingSuccessL = false;
boolean movingSuccessR = false;
// Deviation in pixels from the route (error value)
int downInaccuracy = 30; // Down
int lnrInaccuracy = 10; // Left and Right
// Minimum distance to apply move (300 px in down and 100 to the left/right)
int downMinDistance = 300;
int lnrMinDistance = 50;
Point oldCoordsL = new Point(0, 0); // Old coordinates left
Point oldCoordsR = new Point(0, 0); // Old coordinates right
Point startPointL = new Point(0, 0);
Point startPointR = new Point(0, 0);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int pIndexL = event.findPointerIndex(event.getPointerId(0));
int pIndexR = 0;
// If we have more than 1 touch read second finger index
if(event.getPointerCount() > 1) pIndexR = event.findPointerIndex(event.getPointerId(1));
// Check if we do not mistake when read fingers id
if(event.getPointerCount() > 1 && event.getX(pIndexL) > event.getX(pIndexR)) {
int tmp = pIndexR;
pIndexR = pIndexL;
pIndexL = tmp;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
movingDownL = true; // Start moving fingers
movingDownR = true;
movingSuccessL = false;
movingSuccessR = false;
// Get start point left and right if we need
if(event.getPointerCount() > 1) {
startPointR = new Point((int) event.getX(pIndexR), (int) event.getY(pIndexR));
oldCoordsR = new Point((int) event.getX(pIndexR), (int) event.getY(pIndexR));
}
startPointL = new Point((int) event.getX(pIndexL), (int) event.getY(pIndexL));
oldCoordsL = new Point((int) event.getX(pIndexL), (int) event.getY(pIndexL));
break;
case MotionEvent.ACTION_MOVE:
// Add right finger handler
if(event.getPointerCount() > 1) {
if(!movingDownR) {
// Check if we still moving to down
if(Math.abs(oldCoordsR.x - event.getX(pIndexR)) < downInaccuracy &&
oldCoordsR.y < event.getY(pIndexR)) break;
// Start moving to the right
if(Math.abs(oldCoordsR.y - event.getY(pIndexR)) < lnrInaccuracy &&
oldCoordsR.x > event.getX(pIndexR) && !movingRight) {
movingRight = true;
startPointR = new Point(new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR)));
}
}else {
if (Math.abs(oldCoordsR.x - event.getX(pIndexR)) > downInaccuracy ||
oldCoordsR.y < event.getY(pIndexR)) {
movingDownR = false;
break;
} else if(findDistance(startPointR,
new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR))) >= downMinDistance){
// Start moving to the left/right
movingDownR = false;
}
}
}
// Left finger handler by default even if we got only one touch
// Check if we need move to any side
if(!movingDownL) {
// Check if we still moving to down
if(Math.abs(oldCoordsL.x - event.getX(pIndexL)) < downInaccuracy &&
oldCoordsL.y < event.getY(pIndexL)) break;
// Start moving to the left
if(Math.abs(oldCoordsL.y - event.getY(pIndexL)) < lnrInaccuracy &&
oldCoordsL.x < event.getX(pIndexL) && !movingLeft) {
movingLeft = true;
startPointL = new Point(new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL)));
}
}else {
if (Math.abs(oldCoordsL.x - event.getX(pIndexL)) > downInaccuracy ||
oldCoordsL.y > event.getY(pIndexL)) {
movingDownL = false;
break;
} else if(findDistance(startPointL,
new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL))) >= downMinDistance){
// Start moving to the left/right
movingDownL = false;
}
}
// Left move handler
if(movingLeft) {
if (Math.abs(oldCoordsL.y - event.getY(pIndexL)) > lnrInaccuracy ||
oldCoordsL.x > event.getX(pIndexL)) {
movingLeft = false;
break;
} else if(findDistance(startPointL,
new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL))) >= lnrMinDistance) {
movingLeft = false;
movingSuccessL = true; // L from left finger is OK
}
}
// Right move handler
if(movingRight) {
if (Math.abs(oldCoordsR.y - event.getY(pIndexR)) > lnrInaccuracy ||
oldCoordsR.x < event.getX(pIndexR)) {
movingRight = false;
break;
} else if(findDistance(startPointR,
new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR))) >= lnrMinDistance) {
movingRight = false;
movingSuccessR = true; // L from right finger is OK
}
}
if(movingSuccessL && movingSuccessR) {
Toast.makeText(this, "Yeah, it's look like double L", Toast.LENGTH_SHORT).show();
} else if(movingSuccessL) Toast.makeText(this, "Yeah, it's look like L", Toast.LENGTH_SHORT).show();
oldCoordsL = new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL));
oldCoordsR = new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR));
break;
case MotionEvent.ACTION_UP:
movingDownL = false;
movingDownR = false;
movingLeft = false;
movingRight = false;
break;
default:
return false;
}
return true;
}
private double findDistance(Point p1, Point p2) {
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
}
}