Android 自定义View----多点触摸反馈

多点触摸和单点不同,只要了解每个触摸点的属性即可

public class PaintingView extends View {

    Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    // 轻量级Map
    SparseArray<Path> pathMap = new SparseArray<>();

    public PaintingView(Context context) {
        super(context);
    }

    public PaintingView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public PaintingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    {
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(UnitUtil.dp2px(5));
        // 设置画笔但始末端样式
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        // 设置拐角样式
        mPaint.setStrokeJoin(Paint.Join.ROUND);
    }

    /*
     多点触摸必须了解:

     触摸事件针对view,不是针对point
     每个触摸点都会有 x , y , index , id 四个属性:
        ① event.getX()等同于event.getX(0)
        ② event.getY()等同于event.getY(0)
        ③ index 用来遍历(会变)  event.getActionIndex()
        ④ id 用来追踪(不会变)   event.getPointerId(actionIndex)

     假设第一个手指按下,第二个手指按下,第一个手指抬起:剩下的触摸点id不会边,index会变为0

     连续三个手指触摸屏幕,第二个手指抬起然后再触摸屏幕:
         第二个手指抬起,第三个手指的index会变为1,id不变
         第二个手指再按下,第二个触摸点会根据id重新复用index为1,第三个手指index恢复2
     */
    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getActionMasked()) {
            // 第一个手指,或者多手指 按下
            case ACTION_DOWN:
            case ACTION_POINTER_DOWN:

                int actionIndex = event.getActionIndex();
                // id是不变唯一的
                int pointerId = event.getPointerId(actionIndex);
                Path path = new Path();
                path.moveTo(event.getX(actionIndex), event.getY(actionIndex));
                pathMap.append(pointerId, path);
                invalidate();
                break;
            case ACTION_MOVE:
                for (int i = 0; i < event.getPointerCount(); i++) {
                    pointerId = event.getPointerId(i);
                    path = pathMap.get(pointerId);
                    path.lineTo(event.getX(i), event.getY(i));
                }
                invalidate();
                break;
            case ACTION_UP:
            case ACTION_POINTER_UP:
                pointerId = event.getPointerId(event.getActionIndex());
                pathMap.remove(pointerId);
                invalidate();
                break;
        }
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 遍历所有 path 进行绘制
        for (int i = 0; i < pathMap.size(); i++) {
            Path path = pathMap.valueAt(i);
            canvas.drawPath(path, mPaint);
        }
    }
    
}

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值