当前位置: 移动技术网 > 移动技术>移动开发>Android > android绘制触点轨迹的代码

android绘制触点轨迹的代码

2019年07月23日  | 移动技术网移动技术  | 我要评论
本文实例为大家分享了android绘制触点轨迹的具体代码,供大家参考,具体内容如下 重点函数是ontouchevent(),所有的触摸事件都会在view的这个函数里面处理

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

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

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网