android canvas画图、涂鸦断续

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/github_36617621/article/details/68923071

mCanvas.drawLine 方法画出来的线可能会断断续续,原因是onTouchEvent中的move方法并不是每个点都调用的,所以需要在点没有调用方法的时候让两点之间生成二次贝塞尔曲线

改进前代码:

    private void initDraw() {
        mIvMode1Anim.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:

                        Log.d(TAG, "onTouch: ==================ACTION_DOWN==================");
                        //创建画纸
                        if (mBitmap == null) {
                            mBitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);

                            //创建画布
                            mCanvas = new Canvas(mBitmap);
                            //将背景设置为透明
                            mCanvas.drawColor(Color.WHITE);
                            //创建画笔
                            mPaint = new Paint();
                            mPaint.setColor(Color.BLACK);//画笔的颜色
                            mPaint.setStrokeWidth(20);//画笔的粗细
                        }

                        //获取坐标
                        mStartX = event.getX();
                        mStartY = event.getY();
                        break;

                    case MotionEvent.ACTION_MOVE:
                        Log.d(TAG, "onTouch: ==================ACTION_MOVE==================");
                        mCurrentX = event.getX();
                        mCurrentY = event.getY();
                        //绘制直线
                        mCanvas.drawLine(mStartX, mStartY, mCurrentX, mCurrentY, mPaint);
                        //第二条线的起始点,就是上一条的重点
                        mStartX = mCurrentX;
                        mStartY = mCurrentY;

                        //将bitmap展示到界面
                        mIvMode1Anim.setImageBitmap(mBitmap);
                        break;

                    case MotionEvent.ACTION_UP:
                        Log.d(TAG, "onTouch: ==================ACTION_UP==================");
                        break;
                }

                //返回true代表了消费了这个事件,那么down后面的move和up事件才能进来
                //返回false,代表不消费这个事件,那么down后面的move和up就进不来
                return true;
            }
        });
    }

改进后代码:

 private Paint mPaint;
    private Path mPath;

    private float mX;
    private float mY;

    private float[] mDownPoint = new float[2];
    private float[] mUpPoint = new float[2];

    private DrawCallBack mBack;

    public DrawView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    private void initView() {
        mPaint = new Paint();
        mPath = new Path();

        mPaint.setAntiAlias(true);
        mPaint.setStyle(Style.STROKE);
        mPaint.setStrokeWidth(20);
        mPaint.setColor(Color.BLACK);

        // 抗锯齿
        mPaint.setAntiAlias(true);
        // 防抖动
        mPaint.setDither(true);
    }

    public void setCallBack(DrawCallBack callBack) {
        this.mBack = callBack;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(mPath, mPaint);
    }

    //手指点下屏幕时调用
    private void touchDown(MotionEvent event) {

        //mPath.rewind();  
        //重置绘制路线,即隐藏之前绘制的轨迹  
        mPath.reset();
        float x = event.getX();
        float y = event.getY();

        mX = x;
        mY = y;
        //mPath绘制的绘制起点  
        mPath.moveTo(x, y);
    }

    //手指在屏幕上滑动时调用  
    private void touchMove(MotionEvent event) {
        final float x = event.getX();
        final float y = event.getY();

        final float previousX = mX;
        final float previousY = mY;

        final float dx = Math.abs(x - previousX);
        final float dy = Math.abs(y - previousY);

        //两点之间的距离大于等于3时,生成贝塞尔绘制曲线  
        if (dx >= 3 || dy >= 3) {
            //设置贝塞尔曲线的操作点为起点和终点的一半  
            float cX = (x + previousX) / 2;
            float cY = (y + previousY) / 2;

            //二次贝塞尔,实现平滑曲线;previousX, previousY为操作点,cX, cY为终点  
            mPath.quadTo(previousX, previousY, cX, cY);
            //mPath.lineTo(x, y);

            //第二次执行时,第一次结束调用的坐标值将作为第二次调用的初始坐标值  
            mX = x;
            mY = y;
        }
    }

    public void resetView() {
        mPath.reset();
        invalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownPoint[0] = event.getX();
                mDownPoint[1] = event.getY();
                touchDown(event);
                break;
            case MotionEvent.ACTION_MOVE:
                touchMove(event);
                break;
            case MotionEvent.ACTION_UP:
                mUpPoint[0] = event.getX();
                mUpPoint[1] = event.getY();
                if (mBack != null) {
                    mBack.drawCompose(mDownPoint, mUpPoint);
                }
                //mPath.reset();
                //postInvalidate();
                //
                //isError();
                break;

            default:
                break;
        }
        invalidate();
        return true;
    }

改进后画图的时候就不会出现断断续续的情况.

展开阅读全文

没有更多推荐了,返回首页