需求:多指手势功能性需求
1:双指操作:双指同时在屏幕左半侧向上或向下滑动为音量增加或减少 双指同时在屏幕右半侧向上或向下滑动为背光亮度增加或减少 双指同时在整个屏幕向左或向右滑动为切换上或下一曲 双指同时从左/右屏幕边缘往中间滑动打开左/右快捷应用栏
2:三指操作:三指从上往下滑进入导航功能 三指从下往上滑进入屏保 三指从左往右滑打开指定应用软件 三指从右往左滑返回主页
3:四指操作:长按30s自动上传log 四指下滑关闭屏幕
4:五指操作:五指长按20s进入触摸校正
开发:
package com.emsm.app.gesture;
import android.content.Context;
import android.graphics.PointF;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import androidx.annotation.NonNull;
import com.core.ex.LogHelps;
import com.core.ex.util.HandlerHelps;
/**
* @Author chentao 0000668668
* @Time 2023/6/15
* @Description 多手势管理类 【支持1-5指长按,上下左右滑动区分】
*
*/
public class MultiGestureManager {
private IListener mListener;
private FingerSplit mFingerSplit;
private VelocityTracker mVelocityTracker;
private int mMinimumFlingVelocity;
private int mMaximumFlingVelocity;
private int minVelocity = 50;
public MultiGestureManager(Context context, IListener listener) {
mListener = listener;
mFingerSplit = new FingerSplit();
if (context == null) {
mMinimumFlingVelocity = ViewConfiguration.getMinimumFlingVelocity();
mMaximumFlingVelocity = ViewConfiguration.getMaximumFlingVelocity();
} else {
final ViewConfiguration configuration = ViewConfiguration.get(context);
mMinimumFlingVelocity = configuration.getScaledMinimumFlingVelocity();
mMaximumFlingVelocity = configuration.getScaledMaximumFlingVelocity();
}
}
private long[] mGingerLongClickTime;
/**
* 设置手指长按的时间
*
* @param delayMillis
* @return
*/
public MultiGestureManager setGingerLongClickTime(long... delayMillis) {
if (delayMillis == null || delayMillis.length != 5) {
new StringIndexOutOfBoundsException("delayMillis != null && delayMillis.length == 5");
}
mGingerLongClickTime = delayMillis;
return this;
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mListener.onDown(event);
}
final boolean multiFingerProcessed = mFingerSplit.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) {
mListener.onUp(event);
}
return multiFingerProcessed;
}
public static final int SINGLE_GINGER = 1, SINGLE_GINGER_LONG_CLICK = SINGLE_GINGER;
public static final int DOUBLE_GINGER = 2, DOUBLE_GINGER_LONG_CLICK = DOUBLE_GINGER;
public static final int THREE_GINGER = 3, THREE_GINGER_LONG_CLICK = THREE_GINGER;
public static final int FOUR_GINGER = 4, FOUR_GINGER_LONG_CLICK = FOUR_GINGER;
public static final int FIVE_GINGER = 5, FIVE_GINGER_LONG_CLICK = FIVE_GINGER;
private Handler mHandler = HandlerHelps.createHandler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
switch (msg.what) {
case SINGLE_GINGER_LONG_CLICK:
mListener.onLongPress(GestureEvent.SINGLE_GINGER_LONG_CLICK);
break;
case DOUBLE_GINGER_LONG_CLICK:
mListener.onLongPress(GestureEvent.DOUBLE_GINGER_LONG_CLICK);
break;
case THREE_GINGER_LONG_CLICK:
mListener.onLongPress(GestureEvent.THREE_GINGER_LONG_CLICK);
break;
case FOUR_GINGER_LONG_CLICK:
mListener.onLongPress(GestureEvent.FOUR_GINGER_LONG_CLICK);
break;
case FIVE_GINGER_LONG_CLICK:
mListener.onLongPress(GestureEvent.FIVE_GINGER_LONG_CLICK);
break;
}
return false;
}
});
private class FingerSplit {
private MotionEvent mStartMultiEvent;
private MotionEvent mLastMultiEvent;
private float mLastFocusX;
private float mLastFocusY;
private float mDownFocusX;
private float mDownFocusY;
private int mRecordMaxPointerCount;
public boolean onTouchEvent(MotionEvent ev) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(ev);
boolean handled = false;
float sumX = 0, sumY = 0;
float focusX = 0, focusY = 0;
mRecordMaxPointerCount = Math.max(mRecordMaxPointerCount, ev.getPointerCount());
if (mRecordMaxPointerCount == ev.getPointerCount()) {
for (int i = 0; i < mRecordMaxPointerCount; i++) {
sumX += ev.getX(i);
sumY += ev.getY(i);
}
focusX = sumX / mRecordMaxPointerCount;
focusY = sumY / mRecordMaxPointerCount;
}
switch (ev.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
LogHelps.i("ACTION_DOWN_recordMaxPointerCount:" + mRecordM