最新Android9开发之多点触控画图划线实例讲解(可以用于LCD屏幕测试) XML布局文件 首先看布局文件,直接上代码: 简单解释一下:
首先看布局文件,直接上代码:
简单解释一下:
1.采用了ConstraintLayout的布局,布局中只有一个自定义的控件名叫BezierGestureTrackView;
2.要引用自定义控件,就必须写出完整的包名,这里是com.example.lcd.BezierGestureTrackView;
接下来我们就看一下这个自定义控件
public class BezierGestureTrackView extends View {
public BezierGestureTrackView(Context context) {
super(context);
}
Paint paint;
public BezierGestureTrackView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);//设置画笔的填充模式
paint.setStrokeJoin(Paint.Join.ROUND);//设置画笔图形接触时笔迹的形状
paint.setStrokeCap(Paint.Cap.ROUND);//设置画笔离开画板时笔迹的形状
paint.setStrokeWidth(30);//设置画笔粗细
paint.setAntiAlias(true);//设置抗锯齿
}
//新建两个SparseArray用来保存我们画出的Path对象,具体为什么之后会解释
//MactivePointers用来保存当前正在画的Path
SparseArray mActivePointers = new SparseArray();
//truePointers用来保存所有的Path,在onDraw()方法里面我们也是绘制这里的所有Path
SparseArray truePointers = new SparseArray();
//重写onTouchEvent()方法
@Override
public boolean onTouchEvent(MotionEvent event) {
//获取当前DOWN或者UP的是手指的index
int curPointerIndex = event.getActionIndex();
//通过index获得当前手指的id
int curPointerId = event.getPointerId(curPointerIndex);
//获取当前正在发生的事件
int actionMasked = event.getActionMasked();
switch (actionMasked) {
//不管是第一个还是第N个手指落下,都执行以下方法:
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
//新建一个PointF对象用来保存点的坐标
PointF pointF = new PointF();
pointF.x = event.getX(curPointerIndex);
pointF.y = event.getY(curPointerIndex);
//每当有手指下落时,都新建一个Path,并移动到手指落下的点
Path p = new Path();
p.moveTo(pointF.x, pointF.y);
//将新建的path添加到mActivePointers中
mActivePointers.append(curPointerId, p);
break;
case MotionEvent.ACTION_MOVE:
//当有手指移动时,遍历mActivePointers,注意这里遍历的条件并不是mActivePointers.size(),而是event.getPointerCount()
//也就是当前所有在滑动的手指数,因为在MotionEvent.ACTION_UP事件中,抬起的手指已经从mActivePointers中删除了
for (int size = event.getPointerCount(), i = 0; i < size; i++) {
//获取mActivePointers中的每一个Path
Path path = mActivePointers.get(event.getPointerId(i));
if (path != null) {
//将得到的点连线
path.lineTo(event.getX(i), event.getY(i));
//这一步很关键:将得到的Path加入到truePointers中
//注意,这里传入的Path的ID是以truePointers.size()做编号的,十分巧妙
truePointers.append(truePointers.size(), path);
//重绘页面,这里会自动调用onDraw()
invalidate();
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
//当手指抬起时,从mActivePointers中将抬起的手指删除
mActivePointers.remove(curPointerId);
break;
}
return true;
}
@Override
protected void onDraw(canvas canvas) {
canvas.drawColor(Color.WHITE);
//遍历truePointers
for (int size = truePointers.size(), i = 0; i < size; i++) {
Path path = truePointers.valueAt(i);
//绘制truePointers里的所有Path
canvas.drawPath(path, paint);
}
}
}
如果在onDraw()函数里面遍历的是mActivePointers,则下一次调用invalidate()重绘页面时,上一次画的线就会小时,原因有两个:
(1)根据手指落下的顺序,每个手指都会被分配一个PointerIndex(每次都从0开始),根据PointerIndex可以通过event.getPointerId(curPointerIndex)找到对应的ID,我们时以这个ID为编号将Path传入SparseArray的,为了节约内存,Android的算法会将离开的手指的ID赋予下一个落下的手指,这导致ID会因为有手指反复下落离开而重复
(2)当传入SparseArray的Path的ID相同时,SparseArray不会增加一个新的Path,而是会修改原来的Path
这样就解释清楚了,之所以上一次绘制的线会消失,是因为每次传入的Path都覆盖了原来的Path,这也是为什么我们要新建两个SparseArray的原因
关于PointerIndex的分配算法,可以参考这篇文章:Android 多点触控算法理解(Multi-touch)
SparseArray:SparseArray详解
如果你不需要其他功能,将控件加入到布局,Activity不用做任何修改就可以开始画图啦!
第一次发帖,如有错误还请谅解!
--结束END--
本文标题: 最新Android9开发之多点触控画图划线实例讲解(可以用LCD屏幕测试)SDK29
本文链接: https://www.lsjlt.com/news/29448.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-01-21
2023-10-28
2023-10-28
2023-10-27
2023-10-27
2023-10-27
2023-10-27
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0