欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android绘制触点轨迹的代码

程序员文章站 2023-08-15 22:23:25
本文实例为大家分享了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);
 }
}

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