美文网首页Android 自定义viewAndroid Other
Android 类似一笔画游戏的Canvas实现

Android 类似一笔画游戏的Canvas实现

作者: cuckoochun | 来源:发表于2022-05-17 11:05 被阅读0次

    直接上效果:


    11.jpg
    22.jpg 33.jpg 44.jpg 55.jpg

    还实现了前进,后退,清除功能
    下面是主要代码:

    package com.ltmb.demo;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.PorterDuff;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.Toast;
    
    import com.socks.library.KLog;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author chenshichun
     * 创建日期:2022/4/25
     * 描述:
     */
    public class DrawView extends View implements View.OnClickListener {
    
        private final Canvas canvas;//声明画笔
        private final Paint paint;//声明画布
        private final Paint surfacePaint;//声明画布
        private final Bitmap bitmap;//声明位图
        private final Paint textPaint;//声明画布
        private final Context context;
        private final List<PointBean> pointBeanList = new ArrayList();// 点集合
        private final List<PointBean> pointBeanListCopy = new ArrayList();// 点集合备份数据,用于前进
        private final List<LineBean> lineBeansList = new ArrayList();// 线集合
    
        public DrawView(Context context) {
            super(context);
            this.context = context;
            // TODO 自动生成的构造函数存根
            // bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test).copy(Bitmap.Config.ARGB_8888, true);//设置位图的宽高
            bitmap = Bitmap.createBitmap(1280, 1800, Bitmap.Config.ALPHA_8);//设置位图的宽高
            canvas = new Canvas(bitmap);
    
            // 点和线paint
            paint = new Paint();//创建一个画笔
            paint.setStyle(Paint.Style.STROKE);//设置非填充
            paint.setStrokeWidth(10);//笔宽5像素
            paint.setColor(Color.parseColor("#197AFF"));
            paint.setAntiAlias(true);//锯齿不显示
            paint.setDither(true);//设置图像抖动处理
            paint.setStrokeJoin(Paint.Join.ROUND);//设置图像的结合方式
            paint.setStrokeCap(Paint.Cap.ROUND);//设置画笔为圆形样式
    
            // 面paint
            surfacePaint = new Paint(Paint.DITHER_FLAG);//创建一个画笔
            surfacePaint.setStyle(Paint.Style.FILL);//设置填充
            surfacePaint.setStrokeWidth(5);//笔宽5像素
            surfacePaint.setColor(Color.parseColor("#54197AFF"));
            surfacePaint.setAntiAlias(true);//锯齿不显示
            surfacePaint.setDither(true);//设置图像抖动处理
            surfacePaint.setStrokeJoin(Paint.Join.ROUND);//设置图像的结合方式
            surfacePaint.setStrokeCap(Paint.Cap.ROUND);//设置画笔为圆形样式
    
            // 文字paint
            textPaint = new Paint(Paint.DITHER_FLAG);//创建一个画笔
            textPaint.setStyle(Paint.Style.FILL);//设置填充
            textPaint.setStrokeWidth(2);//笔宽5像素
            textPaint.setColor(Color.parseColor("#ffffffff"));
            textPaint.setTextSize(56f);
            textPaint.setAntiAlias(true);//锯齿不显示
            textPaint.setDither(true);//设置图像抖动处理
            textPaint.setStrokeJoin(Paint.Join.ROUND);//设置图像的结合方式
            textPaint.setStrokeCap(Paint.Cap.ROUND);//设置画笔为圆形样式
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawBitmap(bitmap, 0, 0, paint);
        }
    
        private boolean isDraw = false;
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            int action = event.getAction() & MotionEvent.ACTION_MASK;
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    float currentX = event.getX();
                    float currentY = event.getY();
                    if (isRestart) {
                        PointBean pointBean = new PointBean();
                        pointBean.setX(currentX);
                        pointBean.setY(currentY);
                        pointBeanList.add(pointBean);
                        pointBeanListCopy.add(pointBean);
    
                        if (pointBeanListCopy.size() < pointBeanList.size()) {// 说明是后退以后再点击
                            pointBeanList.clear();
                            pointBeanList.addAll(pointBeanListCopy);
                        }
    
                        drawPointLines(pointBeanList);
                    } else {// 点击设置长度
                        // 创建线集合数据
                        lineBeansList.clear();
                        KLog.d("chenshichun", pointBeanList);
                        for (int i = 0; i < pointBeanList.size(); i++) {
                            LineBean lineBean = new LineBean();
                            if (i + 1 < pointBeanList.size()) {
                                lineBean.x = pointBeanList.get(i).getX();
                                lineBean.y = pointBeanList.get(i).getY();
                                lineBean.x1 = pointBeanList.get(i + 1).getX();
                                lineBean.y1 = pointBeanList.get(i + 1).getY();
                                lineBeansList.add(lineBean);
                            }
                        }
    
                        KLog.d("chenshichun", lineBeansList);
                        KLog.d("chenshichun", "currentX  " + currentX + "  currentY  " + currentY);
                        isDraw = false;
                        for (LineBean lineBean : lineBeansList) {
                            if (((currentX < lineBean.x && currentX > lineBean.x1)
                                    || (currentX > lineBean.x && currentX < lineBean.x1)) &&
                                    ((currentY < lineBean.y && currentY > lineBean.y1)
                                            || (currentY > lineBean.y && currentY < lineBean.y1))) {// 点击的点所在的线
                                Toast.makeText(context, "ss", Toast.LENGTH_SHORT).show();
                                KLog.d("chenshichun", lineBean);
                                textPaint.setColor(getResources().getColor(R.color.white));
                                canvas.drawText("100", (lineBean.x + lineBean.x1) / 2, (lineBean.y + lineBean.y1) / 2, textPaint);
                                invalidate();
                                isDraw = true;
                            }
                        }
    
                        if (!isDraw) {
                            Toast.makeText(context, "请点击对应线", Toast.LENGTH_SHORT).show();
                        }
    
                    }
                    break;
                case MotionEvent.ACTION_POINTER_DOWN:
    
                    break;
                case MotionEvent.ACTION_MOVE:
                    break;
    
                case MotionEvent.ACTION_UP:
                    break;
            }
            return true;
        }
    
        /*
         * 画点线面
         * */
        private boolean isRestart = true;
        Path path1;
        Path path2;
    
        private void drawPointLines(List<PointBean> beanList) {
            // 每次清除画布
            canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
    
            if (beanList.size() > 1) {
                path1 = new Path();// 线的颜色蓝色
                path2 = new Path();// 面的颜色淡蓝色
    
                //  判断最后一个点和第一个点重合
                if (Math.abs(beanList.get(0).getX() - beanList.get(beanList.size() - 1).getX()) < 30
                        && Math.abs(beanList.get(0).getY() - beanList.get(beanList.size() - 1).getY()) < 30) {
                    beanList.get(beanList.size() - 1).setX(beanList.get(0).getX());
                    beanList.get(beanList.size() - 1).setY(beanList.get(0).getY());
    
                    for (int i = 0; i < beanList.size(); i++) {
                        if (i == 0) {
                            path1.moveTo(beanList.get(i).getX(), beanList.get(i).getY());
                            path2.moveTo(beanList.get(i).getX(), beanList.get(i).getY());
                        } else {
                            path1.lineTo(beanList.get(i).getX(), beanList.get(i).getY());
                            path2.lineTo(beanList.get(i).getX(), beanList.get(i).getY());
                        }
                    }
                    path2.close();
                    isRestart = false;
                    surfacePaint.setStyle(Paint.Style.FILL);
                } else {
                    for (int i = 0; i < beanList.size(); i++) {
                        if (i == 0) {
                            path1.moveTo(beanList.get(i).getX(), beanList.get(i).getY());
                        } else {
                            path1.lineTo(beanList.get(i).getX(), beanList.get(i).getY());
                        }
                    }
                }
                canvas.drawPath(path1, paint);
                canvas.drawPath(path2, surfacePaint);
            } else {
                canvas.drawPoint(beanList.get(0).getX(), beanList.get(0).getY(), paint);
            }
            invalidate();//使绘画动作生效
        }
    
        @Override
    
        public void onClick(View v) {
    
    
        }
    
        /*
         * 前进
         * */
        public void forward() {
            if (pointBeanListCopy.size() < pointBeanList.size()) {
                pointBeanListCopy.add(pointBeanList.get(pointBeanListCopy.size()));
                drawPointLines(pointBeanListCopy);
                invalidate();//使绘画动作生效
            }
        }
    
        /*
         * 后退
         * */
        public void backOff() {
            isRestart = true;
            pointBeanListCopy.remove(pointBeanListCopy.size() - 1);
            drawPointLines(pointBeanListCopy);
            invalidate();//使绘画动作生效
        }
    
        public void clear() {
            isRestart = true;
            pointBeanList.clear();
            pointBeanListCopy.clear();
            canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
            invalidate();//使绘画动作生效
        }
    
    }
    
    
    

    完整代码:https://github.com/chenshichun/DrawCanvas-android
    欢迎收藏点赞

    相关文章

      网友评论

        本文标题:Android 类似一笔画游戏的Canvas实现

        本文链接:https://www.haomeiwen.com/subject/elggurtx.html