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()
/**
*Returnthekindofactionbeingperformed.
*Considerusing{@link#getActionMasked}and{@link#getActionIndex}toretrieve
*theseparatemaskedactionandpointerindex.
*@returnTheaction,suchas{@link#ACTION_DOWN}or
*thecombinationof{@link#ACTION_POINTER_DOWN}withashiftedpointerindex.
*/
publicfinalintgetAction(){
returnnativeGetAction(mNativePtr);//注意返回值表达式
}
getActionIndex()
publicstaticfinalintACTION_POINTER_INDEX_MASK=0xff00;
publicstaticfinalintACTION_POINTER_INDEX_SHIFT=8;
/**
*For{@link#ACTION_POINTER_DOWN}or{@link#ACTION_POINTER_UP}
*asreturnedby{@link#getActionMasked},thisreturnstheassociated
*pointerindex.
*Theindexmaybeusedwith{@link#getPointerId(int)},
*{@link#getX(int)},{@link#getY(int)},{@link#getPressure(int)},
*and{@link#getSize(int)}togetinformationaboutthepointerthathas
*gonedownorup.
*@returnTheindexassociatedwiththeaction.
*/
publicfinalintgetActionIndex(){
//这个表达式实际就是说取getAction()函数返回值的高8位
return(nativeGetAction(mNativePtr)&ACTION_POINTER_INDEX_MASK)
>>ACTION_POINTER_INDEX_SHIFT;
}
getActionMasked()
publicstaticfinalintACTION_MASK=0xff;
/**
*Returnthemaskedactionbeingperformed,withoutpointerindexinformation.
*Use{@link#getActionIndex}toreturntheindexassociatedwithpointeractions.
*@returnTheaction,suchas{@link#ACTION_DOWN}or{@link#ACTION_POINTER_DOWN}.
*/
publicfinalintgetActionMasked(){
//这个表达式的意思就是说取getAction()函数的低8位
returnnativeGetAction(mNativePtr)&ACTION_MASK;
}
总结:这就很简单明了了,Acton包含两个部分,高8位表示触摸点的index,低8位表示具体的事件。
注意这里的触摸点的index,指的是Action中的,而不是event中的,这是两个概念。
getPointerId()和findPointerIndex()
getPointerID()
//注意函数的注释第一句的说明,表示,返回的id叫pointeridentifier,是和event里面的数据关联的
/**
*Returnthepointeridentifierassociatedwithaparticularpointer
*dataindexinthisevent.Theidentifiertellsyoutheactualpointer
*numberassociatedwiththedata,accountingforindividualpointers
*goingupanddownsincethestartofthecurrentgesture.
*@parampointerIndexRawindexofpointertoretrieve.Valuemaybefrom0
*(thefirstpointerthatisdown)to{@link#getPointerCount()}-1.
*/
publicfinalintgetPointerId(intpointerIndex){
returnnativeGetPointerId(mNativePtr,pointerIndex);
}
findPointerIndex()
//注意函数的注释里面第一句,意思是提供一个pointeridentifier,返回event中对应数据的index
//indexofdata的作用是传给event.getX()等其他的函数来获取坐标等信息
//所以这个函数的名字改成getPointerDataIndex比较合适
/**
*Givenapointeridentifier,findtheindexofitsdataintheevent.
*
*@parampointerIdTheidentifierofthepointertobefound.
*@returnReturnseithertheindexofthepointer(forusewith
*{@link#getX(int)}etal.),or-1ifthereisnodataavailablefor
*thatpointeridentifier.
*/
publicfinalintfindPointerIndex(intpointerId){
returnnativeFindPointerIndex(mNativePtr,pointerId);
}
总结:这里引入了两个概念,一个是pointeridentifier,很好理解,就是指针的id,一个是indexofitsdata.
总结
MotionEvent.getAction返回的是actionIndex和mask的连接体,通过actionIndex可以获取到对应的pointerID,通过pointerID可以获取到对应数据包的ID,然后通过getX()来获取对应的数据信息
基本的使用方法示例
intindex=event.getActionIndex(); intid=event.getPointerId(index); intpointerIndex=event.findPointerIndex(id); intx=getX(pointerIndex); inty=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()来获取存在缓存中的数据,后面的例子中有说明
实例
获取默认屏幕长和宽的代码
WindowManagermanager=(WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE); DisplayMetricsdisplayMetrics=newDisplayMetrics(); Displaydisplay=manager.getDefaultDisplay(); display.getMetrics(displayMetrics); screenW=displayMetrics.widthPixels; screenH=displayMetrics.heightPixels;
自定义View的代码
importandroid.content.Context;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.graphics.Paint;
importandroid.graphics.PorterDuff;
importandroid.graphics.PorterDuffXfermode;
importandroid.util.AttributeSet;
importandroid.util.Log;
importandroid.view.MotionEvent;
importandroid.view.View;
importjava.util.HashMap;
importjava.util.Map;
publicclassTouchTraceViewextendsView
{
ContextmContext;
privatePaintline_paint,text_paint,countPaint;
intscreenW,screenH;
FactoryApplicationapp;
privateintpaintColor=Color.RED;
MappointMap;
floatback_x1,back_y1,back_x2,back_y2;
publicTouchTraceView(Contextcontext,AttributeSetattr)
{
super(context,attr);
mContext=context;
app=;//作用仅仅是获取默认屏幕的长和宽
this.screenH=app.screenH;
this.screenW=app.screenW;
pointMap=newHashMap<>();
initPaint();
}
privatevoidinitPaint()
{
line_paint=newPaint();
line_paint.setAntiAlias(true);
line_paint.setColor(paintColor);
text_paint=newPaint();
text_paint.setAntiAlias(true);
text_paint.setColor(Color.BLUE);
text_paint.setTextSize(30);
countPaint=newPaint();
countPaint.setAntiAlias(true);
countPaint.setColor(Color.GREEN);
countPaint.setTextSize(60);
}
@Override
protectedvoidonDraw(Canvascanvas)
{
super.onDraw(canvas);
intnum=pointMap.size();
if(num==0)
{
clearDraw(canvas);
return;
}
for(Map.Entryentry:pointMap.entrySet())
{
TouchPointpoint=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
publicbooleanonTouchEvent(MotionEventevent)
{
intindex=event.getActionIndex();
intid=event.getPointerId(index);
intpointerIndex=event.findPointerIndex(id);
intpointerCount=event.getPointerCount();
inthistorySize=event.getHistorySize();
switch(event.getActionMasked())
{
caseMotionEvent.ACTION_POINTER_DOWN:
pointMap.put(pointerIndex,newTouchPoint(event.getX(pointerIndex),event.getY(pointerIndex)));
break;
caseMotionEvent.ACTION_POINTER_UP:
pointMap.remove(pointerIndex);
break;
caseMotionEvent.ACTION_MOVE:
for(inth=0;hscreenW/2&&Math.abs(back_y1-back_y2)>screenH/2)
{
callOnClick();
}
pointMap.clear();
break;
default:
break;
}
if(event.getPointerCount()==0)pointMap.clear();
invalidate();
returntrue;
}
classTouchPoint
{
publicfloatx=0;
publicfloaty=0;
TouchPoint(floatx,floaty)
{
this.x=x;
this.y=y;
}
}
voidclearDraw(Canvascanvas)
{
Paintpaint=newPaint();
paint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawPaint(paint);
paint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.SRC));
canvas.drawColor(Color.WHITE);
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。