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.Entry entry: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;h screenW/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); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。