自定义view系列---手指绘制曲线

需求:实现手指在屏幕上滑动,绘制出手指的滑动轨迹,并提供一键清除轨迹的功能。
手指在屏幕上滑动,view会收到一系列的滑动事件 :DOWN —> MOVE —> … —> MOVE —> UP/CANCEL。我们知道曲线是由若干小段的直线组成的,手指在屏幕上随意滑动,肯定是曲线的路径,但是这曲线是由若干MOVE事件上报的滑动点组成的。因此,要实现这个需求,就需要监听手指的滑动事件,系统每次上报滑动事件时,我们就绘制一段直线。

我们自定义一个view叫DrawLineByFingerView,继承View。根据上面的分析,我们要关注view的onTouchEvent方法,在该方法内,我们能接收到滑动事件。

那么问题来了,我们是在onTouchEvent中接收到滑动事件,但是在View的onDraw中才能拿到Canvas画布,进而才能进行绘制操作。并且我们onDraw方法中每次传入的是一个全新的Canvas,前一次绘制的内容不会自动保存到这个新的Canvas上。因此我们还需要一个称为缓存的画布,将之前所有绘制内容 和 本次move事件的需要绘制的直线 先全部绘制到这个缓存画布上,然后在统一将这个缓存画布的内容 一次性 绘制到view的onDraw方法中传过来的画布上。

1,定义缓存画布

private Bitmap bitmapBuffer;
private Canvas bitmapCanvas;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
   super.onSizeChanged(w, h, oldw, oldh);

   bitmapBuffer = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
   bitmapCanvas = new Canvas(bitmapBuffer);
}

2,onTouchEvent方法中将本次MOVE事件上报的坐标点与上次MOVE事件(或者Down事件)的坐标,两点绘制一条Line,注意是绘制在缓存的Canvas上,然后通过invalidate()方法回调View的onDraw(),将缓存的Canvas的bitMap绘制到view的画布上。

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(bitmapBuffer, 0, 0, paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        //Log.e("cyy","onTouchEvent:("+event.getX()+", "+event.getY()+")");
        switch (action){
            case MotionEvent.ACTION_DOWN:
                preX = event.getX();
                preY = event.getY();
                if(bitmapBuffer.getWidth() == 1){//点过清除曲线的按钮
                    bitmapBuffer = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
                    bitmapCanvas = new Canvas(bitmapBuffer);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                mCurrentX = event.getX();
                mCurrentY = event.getY();

                bitmapCanvas.drawLine(preX, preY, mCurrentX, mCurrentY, paint);
                preX  =mCurrentX;
                preY = mCurrentY;
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                break;
        }

        return true;
    }

现在我们用手指多次任意滑动,在我们的自定义view上就能显示所有手指的滑动轨迹。
还有最后一个问题,我们要做一个 清除曲线 的功能,该功能可以将之前所有绘制的内容全部清除掉,方便进行下一次绘制。
View提供可供外界访问缓存bitMap的接口

public Bitmap getBitmapBuffer(){
        return bitmapBuffer;
    }

public void setBitmapBuffer(Bitmap bitmap){
   bitmapBuffer = bitmap;
}

在Acitvity的layout中加载该view,并且在layout中添加一个 清除按钮,来实现此功能。

清除曲线路径的思路就是:将缓存bitMap的内容清空,这个bitMap对应的Canvas也就没有内容了,再将这个空的bitMap绘制到这个我们的自定义View的Canvas上。

Bitmap bitmap = mDrawLineByFingerView.getBitmapBuffer();
bitmap.recycle();
mDrawLineByFingerView.setBitmapBuffer(Bitmap.createBitmap(1,1, Bitmap.Config.ARGB_8888));
mDrawLineByFingerView.invalidate();//回调view的onDraw()方法

DONE

此系列后续持续更新。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值