android绘制触点轨迹的代码
本文实例为大家分享了android绘制触点轨迹的具体代码,供大家参考,具体内容如下
重点函数是ontouchevent(),所有的触摸事件都会在view的这个函数里面处理
单点触控
单点触控的event是通过event.getaction()获得的,一般最少需要考虑下面这三种情况
motionevent.action_down:
- 手指 初次接触到屏幕 时触发。
motionevent.action_move:
- 手指 在屏幕上滑动 时触发,会多次触发。
motionevent.action_up:
- 手指 离开屏幕 时触发。
多点触控
多点触控的event是通过event.getactionmasked()获得的,一般最少需要考虑下面这个五种情况,因为有多个点需要处理,所以需要判断event是哪一个触摸点的事件,android因此导入了比较多的概念,下面通过对关键函数的解析来说明。
注意:方法的说明中添加了我的注释,请留意。另外,每一组函数和这个模块最后都有我写的总结性的文字。
motionevent提供了很多看似能直接得到触摸点的方法,但是,这些方法并不是直接拿来能用的,具体的关系如下
getaction()和getactionindex()以及getactionmasked()
getaction()
/** * return the kind of action being performed. * consider using {@link #getactionmasked} and {@link #getactionindex} to retrieve * the separate masked action and pointer index. * @return the action, such as {@link #action_down} or * the combination of {@link #action_pointer_down} with a shifted pointer index. */ public final int getaction() { return nativegetaction(mnativeptr);//注意返回值表达式 }
getactionindex()
public static final int action_pointer_index_mask = 0xff00; public static final int action_pointer_index_shift = 8; /** * for {@link #action_pointer_down} or {@link #action_pointer_up} * as returned by {@link #getactionmasked}, this returns the associated * pointer index. * the index may be used with {@link #getpointerid(int)}, * {@link #getx(int)}, {@link #gety(int)}, {@link #getpressure(int)}, * and {@link #getsize(int)} to get information about the pointer that has * gone down or up. * @return the index associated with the action. */ public final int getactionindex() { //这个表达式实际就是说取getaction()函数返回值的高8位 return (nativegetaction(mnativeptr) & action_pointer_index_mask) >> action_pointer_index_shift; }
getactionmasked()
public static final int action_mask = 0xff; /** * return the masked action being performed, without pointer index information. * use {@link #getactionindex} to return the index associated with pointer actions. * @return the action, such as {@link #action_down} or {@link #action_pointer_down}. */ public final int getactionmasked() { //这个表达式的意思就是说取getaction()函数的低8位 return nativegetaction(mnativeptr) & action_mask; }
总结:这就很简单明了了,acton包含两个部分,高8位表示触摸点的index,低8位表示具体的事件。
注意这里的触摸点的index,指的是action中的,而不是event中的,这是两个概念。
getpointerid()和findpointerindex()
getpointerid()
//注意函数的注释第一句的说明,表示,返回的id叫pointer identifier,是和event里面的数据关联的 /** * return the pointer identifier associated with a particular pointer * data index in this event. the identifier tells you the actual pointer * number associated with the data, accounting for individual pointers * going up and down since the start of the current gesture. * @param pointerindex raw index of pointer to retrieve. value may be from 0 * (the first pointer that is down) to {@link #getpointercount()}-1. */ public final int getpointerid(int pointerindex) { return nativegetpointerid(mnativeptr, pointerindex); }
findpointerindex()
//注意函数的注释里面第一句,意思是提供一个pointer identifier,返回event中对应数据的index //index of data的作用是传给event.getx()等其他的函数来获取坐标等信息 //所以这个函数的名字改成getpointerdataindex比较合适 /** * given a pointer identifier, find the index of its data in the event. * * @param pointerid the identifier of the pointer to be found. * @return returns either the index of the pointer (for use with * {@link #getx(int)} et al.), or -1 if there is no data available for * that pointer identifier. */ public final int findpointerindex(int pointerid) { return nativefindpointerindex(mnativeptr, pointerid); }
总结:这里引入了两个概念,一个是pointer identifier,很好理解,就是指针的id,一个是index of its data.
总结
motionevent.getaction返回的是actionindex和mask的连接体,通过actionindex可以获取到对应的pointerid,通过pointerid可以获取到对应数据包的id,然后通过getx()来获取对应的数据信息
基本的使用方法示例
int index = event.getactionindex(); int id = event.getpointerid(index); int pointerindex = event.findpointerindex(id); int x=getx(pointerindex); int y=gety(pointerindex);
motionevent.action_pointer_down:
- 多点触控时按下手指时触发,如果当前只有一个点,则不会触发此事件。
motionevent.action_pointer_down:
- 多点触控抬起手指时触发,如果当前只有一个点,则不会触发此事件。
motionevent.action_down:
- 第一个手指按下时触发
motionevent.action_up:
- 最后一个手指离开时触发
motionevent.action_move:
1.所有的手指滑动时触发此事件
2.如果有多个点,同时移动,需要在action_move里面添加循环语句。
3.考虑到刷新效率的问题,可以通过event.gethistoricalx()和event.gethistoricaly()来获取存在缓存中的数据,后面的例子中有说明
实例
获取默认屏幕长和宽的代码
windowmanager manager=(windowmanager) getapplicationcontext().getsystemservice(context.window_service); displaymetrics displaymetrics=new displaymetrics(); display display=manager.getdefaultdisplay(); display.getmetrics(displaymetrics); screenw=displaymetrics.widthpixels; screenh=displaymetrics.heightpixels;
自定义view的代码
import android.content.context; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.graphics.porterduff; import android.graphics.porterduffxfermode; import android.util.attributeset; import android.util.log; import android.view.motionevent; import android.view.view; import java.util.hashmap; import java.util.map; public class touchtraceview extends view { context mcontext; private paint line_paint, text_paint, countpaint; int screenw, screenh; factoryapplication app; private int paintcolor = color.red; map<integer, touchpoint> pointmap; float back_x1, back_y1, back_x2, back_y2; public touchtraceview(context context, attributeset attr) { super(context, attr); mcontext = context; app = ;//作用仅仅是获取默认屏幕的长和宽 this.screenh = app.screenh; this.screenw = app.screenw; pointmap = new hashmap<>(); initpaint(); } private void initpaint() { line_paint = new paint(); line_paint.setantialias(true); line_paint.setcolor(paintcolor); text_paint = new paint(); text_paint.setantialias(true); text_paint.setcolor(color.blue); text_paint.settextsize(30); countpaint = new paint(); countpaint.setantialias(true); countpaint.setcolor(color.green); countpaint.settextsize(60); } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); int num = pointmap.size(); if (num == 0) { cleardraw(canvas); return; } for (map.entry<integer, touchpoint> entry : pointmap.entryset()) { touchpoint point = entry.getvalue(); canvas.drawline(0, point.y, getwidth(), point.y, line_paint); canvas.drawline(point.x, 0, point.x, getheight(), line_paint); if (num == 1) { canvas.drawtext(" (" + point.x + "," + point.y + ")", screenw / 2, screenh / 2, text_paint); } else { canvas.drawtext(string.valueof(pointmap.size()), screenw / 2, screenh / 2, countpaint); } } } @override public boolean ontouchevent(motionevent event) { int index = event.getactionindex(); int id = event.getpointerid(index); int pointerindex = event.findpointerindex(id); int pointercount = event.getpointercount(); int historysize = event.gethistorysize(); switch (event.getactionmasked()) { case motionevent.action_pointer_down: pointmap.put(pointerindex, new touchpoint(event.getx(pointerindex), event.gety(pointerindex))); break; case motionevent.action_pointer_up: pointmap.remove(pointerindex); break; case motionevent.action_move: for (int h = 0; h < historysize; h++) { for (int p = 0; p < pointercount; p++) { pointmap.put(p, new touchpoint(event.gethistoricalx(p, h), event.gethistoricaly(p, h))); } } for (int p = 0; p < pointercount; p++) { pointmap.put(p, new touchpoint(event.getx(p), event.gety(p))); } break; case motionevent.action_down: pointmap.put(0, new touchpoint(event.getx(pointerindex), event.gety(pointerindex))); back_x1 = event.getx(); back_y1 = event.gety(); break; case motionevent.action_up: back_x2 = event.getx(); back_y2 = event.gety(); if (math.abs(back_x1 - back_x2) > screenw / 2 && math.abs(back_y1 - back_y2) > screenh / 2) { callonclick(); } pointmap.clear(); break; default: break; } if (event.getpointercount() == 0) pointmap.clear(); invalidate(); return true; } class touchpoint { public float x = 0; public float y = 0; touchpoint(float x, float y) { this.x = x; this.y = y; } } void cleardraw(canvas canvas) { paint paint = new paint(); paint.setxfermode(new porterduffxfermode(porterduff.mode.clear)); canvas.drawpaint(paint); paint.setxfermode(new porterduffxfermode(porterduff.mode.src)); canvas.drawcolor(color.white); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。