Android手势检测器
在本教程中,我们将在Android应用程序中讨论和实现手势。
首先,手势可能会有些棘手。
但是一旦掌握,它们真的很方便。
Android手势检测器
手势检测器类用于检测来自用户的触摸事件。
" GestureListener"提供了由用户执行的" MotionEvent"。
您可以使用GestureDetector.SimpleOnGestureListener类来监听手势的子集。
这些手势包括以下内容:
- onDown
- onScroll
- onSingleTap
- onDoubleTap
- onLongPress
- onFling
手势在"动画"中扮演MVP角色。
它们始终可以改善用户体验。
让我们看一下SimpleOnGestureListener类中可用的每种方法:
onDown(MotionEvent e):通知发生向下触发的MotionEvent轻击时。onDoubleTap(MotionEvent e):通知何时双击。onFling(MotionEvent e1,MotionEvent e2,float velocityX,float velocityY):通知快速滑动事件,当它发生在向下MotionEvent的初始和向上匹配的MotionEvent发生时。
我们可以设置猛扑/猛击的速度阈值onLongPress(MotionEvent e):通知长按触发了它的MotionEvent首字母时发生长按。onSingleTapConfirmed(MotionEvent e):通知何时单击。
onShowPress(MotionEvent e):当用户执行了向下MotionEvent但尚未执行上移或者上移时,会发生这种情况。
现在,在下一节中,我们将开发一个带有按钮的简单Android应用程序,可以在其上执行上述手势。
项目结构
Android手势检测器项目结构
代码
下面给出了" activity_main.xml"布局的代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="150dp"
android:layout_height="150dp"
android:text="DO YOUR GESTURES ON ME"
android:textColor="@android:color/white"
android:background="@color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
</android.support.constraint.ConstraintLayout>
MainActivity.java类的代码如下:
package com.theitroad.androidgesturedetector;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnTouchListener(new OnSwipeTouchListener(this) {
public void onSwipeTop() {
Toast.makeText(getApplicationContext(), "Swiped top", Toast.LENGTH_SHORT).show();
}
public void onSwipeRight() {
Toast.makeText(getApplicationContext(), "Swiped right", Toast.LENGTH_SHORT).show();
}
public void onSwipeLeft() {
Toast.makeText(getApplicationContext(), "Swiped left", Toast.LENGTH_SHORT).show();
}
public void onSwipeBottom() {
Toast.makeText(getApplicationContext(), "Swiped bottom", Toast.LENGTH_SHORT).show();
}
});
}
class OnSwipeTouchListener implements View.OnTouchListener {
private final GestureDetector gestureDetector;
public OnSwipeTouchListener(Context ctx) {
gestureDetector = new GestureDetector(ctx, new GestureListener());
}
@Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
private final class GestureListener extends GestureDetector.SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 300;
private static final int SWIPE_VELOCITY_THRESHOLD = 300;
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.i("TAG", "onSingleTapConfirmed:");
Toast.makeText(getApplicationContext(), "Single Tap Detected", Toast.LENGTH_SHORT).show();
return true;
}
@Override
public void onLongPress(MotionEvent e) {
Log.i("TAG", "onLongPress:");
Toast.makeText(getApplicationContext(), "Long Press Detected", Toast.LENGTH_SHORT).show();
}
@Override
public boolean onDoubleTap(MotionEvent e) {
Toast.makeText(getApplicationContext(), "Double Tap Detected", Toast.LENGTH_SHORT).show();
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
onSwipeRight();
} else {
onSwipeLeft();
}
result = true;
}
} else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
onSwipeBottom();
} else {
onSwipeTop();
}
result = true;
}
} catch (Exception exception) {
exception.printStackTrace();
}
return result;
}
}
public void onSwipeRight() {
}
public void onSwipeLeft() {
}
public void onSwipeTop() {
}
public void onSwipeBottom() {
}
}
}
在上面的代码中,在方法中返回false而不是true会导致手势不起作用。
特别地," onDown"可能会导致所有手势无效(如果为假)。
onFling方法有两件事:滑动阈值和速度阈值。
滑动阈值指示在四个方向中任何一个方向上触摸的初始位置和最终位置之间的差异。
速度阈值指示刷卡被称为手势的速度。

