首页 > 系统 > Android > 正文

android绘制触点轨迹的代码

2019-12-12 00:11:01
字体:
来源:转载
供稿:网友

本文实例为大家分享了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); }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表