画板/鼠标垫 自定义view代码:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
/*
*Author:XingHai.Zhao
*Purpose:鼠标垫/画板
*/
public class MouseMat extends View {
public MouseMat(Context context) {
super(context);
}
public MouseMat(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MouseMat(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private Path path;
private Paint paint;
private void init() {
path = new Path();
paint = new Paint();
paint.setColor(Color.CYAN); //颜色
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(10); //边框宽度
setClickable(true);//设置可点击
}
public MouseTouchListener mouseTouchListener;
public interface MouseTouchListener {
void MouseEvent(MotionEvent event);
}
public void setMouseTouchListener(MouseTouchListener mouseTouchListener) {
this.mouseTouchListener = mouseTouchListener;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(event.getX(), event.getY());
break;
case MotionEvent.ACTION_MOVE:
path.lineTo(event.getX(), event.getY());
invalidate();
break;
case MotionEvent.ACTION_UP: // 如果做画板,则注释该UP处理
//手指抬起,清除痕迹
reset();
break;
}
if (mouseTouchListener != null)
mouseTouchListener.MouseEvent(event);
return super.onTouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(path, paint);
}
/*
*Author:XingHai.Zhao
*Purpose: 清除内容
*/
public void reset() {
path.reset();
invalidate();
}
}
如果只需要画板效果,不想要手指抬起清除痕迹的效果,
可以注释掉抬起事件的reset()方法被动调用
如果需要主动清除画板内容,则可以在外部直接调用画板对象的reset()方法
鼠标滑动偏移量抛出:
MouseMat MyMouseMat = findViewById(R.id.mouse_mat);
//手势监听 CSDN-深海呐
MyMouseMat.setMouseTouchListener(new MouseMat.MouseTouchListener() {
@Override
public void MouseEvent(MotionEvent event) {
int num;
float X = event.getX();
float Y = event.getY();
if (lastX != 0) { //过滤0 防止第一次接到时间跳跃
num = (int) (X - lastX);
// 防止多点触控 大距离跳跃
if (num < 100 && num > -100 && num != 0 && Math.abs(num) > 4) {
Log.i(TAG, "X移动:" + num);
//这里抛出正在X偏移量
}
}
if (lastY != 0) {
num = (int) (Y - lastY);
if (num < 100 && num > -100 && num != 0 && Math.abs(num) > 4) {
Log.i(TAG, "Y移动:" + num);
//这里抛出正在Y偏移量
}
}
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.i(TAG, "ACTION_DOWN");
date = new Date();
downTime = date.getTime();//记录按下时间,方便判断点击时间
}
if (event.getAction() == MotionEvent.ACTION_UP) {
Log.i(TAG, "ACTION_UP");
date = new Date();
if ((date.getTime() - downTime) < 200) { //点击判定
Log.i(TAG, "点击触发");
//这里抛出点击事件
}
lastX = 0;
lastY = 0;
}
lastX = X;
lastY = Y;
}
});
这里X和Y的偏移量 分别在对应注释的地方抛出 , 可以将偏移量传输到远程设备上,实现手机屏幕作为鼠标操作远程设备的鼠标移动和点击。
点击事件抛出的地方见代码中注释。
关于偏移量的记录判定有两个核心值:
????????1.正负100值: 过滤掉手指腾空移位,或多指触控的偏移量大跳,这里优化的场景类似与实际鼠标使用场景(比如:鼠标移动到鼠标垫边界,再拿起鼠标放到鼠标垫中间继续移动)。
? ? ? ? 2.绝对值4:过滤鼠标的小幅度移动,另一方面也减少了偏移事件的抛出频率。
这两个值可根据实际体验进行调整。
关于双击事件或者跟多连续点击事件:
? ? ? ? 这边根据点击间隔200毫秒进行判定记录,可根据实际体验进行调整,如果需要更多次点击事件,核心判定思想可以看这里:https://blog.csdn.net/qq_39731011/article/details/114868495
如果感觉文章有帮助到您的话请点个赞吧!
如果有什么问题或者文章错误指出的话欢迎评论区留言!
深海谢过各位同行。
????????
|