触摸事件分为: 单点触摸和多点触摸
一:单点触摸
1. 怎么知道是单点触摸还是多点触摸?
onTouchEvent()方法和onTouch()方法都可以,都可以通过.getAction()返回的是触控的所有信息。
区别:onTouchEvent()是Activity的,onTouch()是View的。
public boolean onTouchEvent(MotionEvent event) {//event 事件
int action = event.getAction();//0,2,2,2,2,2,1
Log.i("test", action);
}
解析:
单点触控事件中,如果getAction()返回的是:
action = 0 代表手指按下
action = 1 代表手指抬起
action = 2 代表手指移动
-----------------------------------------------------
单点触摸案例:绘制一个跟随触控点的圆
public class MyView extends View{
//初始化圆的坐标点
float currentX = 40;
float currentY = 50;
//创建画笔
Paint p = new Paint();
//构造方法
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
//绘制圆
@Override
protected void onDraw(Canvas canvas) { //canvas画布
super.onDraw(canvas);
//设置画笔颜色
p.setColor(Color.RED);
//在画布上绘制圆
canvas.drawCircle(currentX, currentY, 15, p); //15圆的半径
}
//触摸事件
@Override
public boolean onTouchEvent(MotionEvent event) {
//获取事件的坐标
this.currentX = event.getX();
this.currentY = event.getY();
//通知组件重新绘制(重绘)
this.invalidate(); //执行会自动调用onDraw()方法
//返回true表明处理方法已经处理该事件
return true;
}
二:多点触摸
多点触摸注意的方法
event.getAction();//返回触摸的所有信息
当返回的是:
action = 0 代表手指1按下
action = 261 代表手指2按下
action = 517 代表手指3按下
action = 518 代表手指3抬起
action = 262 代表手指2抬起
action = 1 代表手指1抬起
action = 2 代表手指移动
可以通过解析手指的action,拿到每一个的pointIndex和action_code
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();//获得一个触摸事件的所有信息
int pointIndex = action >> 8;//手指的名字(ID)
int action_code = action & 0xff;//手指的行为(动作编码)
Log.i("test","action="+action+" "+pointIndex+" "+action_code);
return true;
}
注意事项:多点触控时获得的action的值是一个八位的十六进制数。
例如:第2个手指按下,action = 261,它对应的十六进制数是0x00000105
其中01代表手指的指针索引
05代表它的动作编码,表示按下事件
06表示抬起。
event.getPointerCount();//返回屏幕上的手指数量
event.getPointerId(指针索引);//返回指针id,相当于每一个手指的名字,一旦确定不再变化
指针索引:每个手指按照顺序编号,随着屏幕上的手指数量不同,每个手指的指针索引会发生改变。
案例:实现多点触摸小球
1. 创建画圆的类Circle
public class Circle {
//初始x, y坐标
public float x;
public float y;
//手指的名字(ID)
public int pointId;
//颜色
int red, blue, green;
//随机数
Random random=new Random();
//构造方法(x坐标,y坐标,手指的名字)
public Circle(float x, float y, int pointId) {
this.x = x;
this.y = y;
this.pointId = pointId;
red=random.nextInt(255);
blue=random.nextInt(255);
green=random.nextInt(255);
}
//画自己(画布,画笔)
public void drawSelf(Canvas canvas, Paint paint){
//给笔设置颜色
paint.setColor(Color.rgb(red,green,blue));
canvas.drawCircle(x,y,100,paint);
}
}
2. 创建触摸类
public class MyTouchView extends View {
//存放触摸点的集合
List<Circle> circles=new ArrayList<>();
//画笔
private Paint paint;
//构造方法
public MyTouchView(Context context) {
super(context);
//初始化画笔
paint = new Paint();
}
public MyTouchView(Context context, AttributeSet attrs) {
super(context, attrs);
//初始化画笔
paint = new Paint();
}
//开始绘制(执行invalidate()时被调用)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//遍历圆的集合
for (Circle circle : circles) {
//遍历时绘制自己
circle.drawSelf(canvas, paint);
}
}
//触摸事件方法
@Override
public boolean onTouchEvent(MotionEvent event) {
//解析手指
int action=event.getAction();
//获取手指的名字
int pointIndex = action >> 8;
//获取手指的坐标
float x = event.getX(pointIndex);
float y = event.getY(pointIndex);
//返回手指的ID
int pointId=event.getPointerId(pointIndex);
//获取手指的行为
int action_code = action & 0xff;
switch (action_code) {
case MotionEvent.ACTION_DOWN://按下行为
case 5:
//实例化圆
Circle circle=new Circle(x,y,pointId);
//将圆添加到集合
circles.add(circle);
break;
case MotionEvent.ACTION_UP://抬起行为
case 6:
//根据ID获得圆
Circle c=getCircle(pointId);
//集合中移除圆
circles.remove(c);
break;
case MotionEvent.ACTION_MOVE://移动行为
//遍历
for (int i = 0; i <circles.size() ; i++) {
//从事件中获得ID
int id=event.getPointerId(i);
//根据ID获得圆
Circle cnew = getCircle(id);
//获得圆的x,y坐标
cnew.x = event.getX(i);
cnew.y = event.getY(i);
}
break;
}
//重新画,重绘
invalidate(); //postInvalidate(); 在线程中重绘
return true;
}
//根据手指的Id,从集合中找到该圆
public Circle getCircle(int pointId){
for (Circle circle : circles) {
if(circle.pointID==pointId){
return circle;
}
}
return null;
}