自定义View——画板

简介: 今天实现的是画板效果image实现原理image根据触摸事件返回的坐标点绘制path路径 @Overridepublic boolean onTouchEvent(MotionEvent event) { x = event.

今天实现的是画板效果

img_4195603269680c9c131a8e49329b2cd8.gif
image

实现原理

img_de92b7e421fc895685a0f18a0090a3f3.png
image

根据触摸事件返回的坐标点绘制path路径

 @Override
public boolean onTouchEvent(MotionEvent event) {
    x = event.getX();
    y = event.getY();
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //当触摸屏幕的时候将点移动到触摸的位置
            path.moveTo(x, y);
            break;
        case MotionEvent.ACTION_MOVE:
            //当滑动的时候将滑动路径连接起来
            path.lineTo(x, y);
            //在滑动的过程中不断更新界面
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            //当手抬起的时候更新界面
            invalidate();
            break;
    }
    return true;
}

canvas绘制路径

//绘制白色背景
canvas.drawColor(Color.WHITE);
//绘制路径
canvas.drawPath(path, paint);

最后保存自己绘制的图像

 public void save() {
    setDrawingCacheEnabled(false);
    setDrawingCacheEnabled(true);
    new Thread(new Runnable() {
        @Override
        public void run() {
            Bitmap drawingCache = getDrawingCache(true);
            File file = new File(getContext().getCacheDir() +  "123.png");
            FileOutputStream fileOutputStream = null;
            try {
                fileOutputStream = new FileOutputStream(file);
                drawingCache.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
                fileOutputStream.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fileOutputStream != null) {
                    try {
                        fileOutputStream.close();
                        try {
                            MediaStore.Images.Media.insertImage(getContext().getContentResolver(),
                                    file.getAbsolutePath(), "sad.png", null);
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        }
                        // 最后通知图库更新
                        getContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + file.getPath())));
                        Log.e("测试", "保存成功");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }).start();
}

完整代码

package com.yuyigufen.customview;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;

/**
 * Created by Administrator on 2018/6/11 0011.
 */

public class MyPaintView extends View {

private float x;
private float y;
private Path path;
private Paint paint;
private Random random;

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

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

private void init() {
    random = new Random();
    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(10);
    paint.setColor(Color.RED);
    path = new Path();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(measureSize(widthMeasureSpec), measureSize(heightMeasureSpec));
}

private int measureSize(int size) {
    int mode = MeasureSpec.getMode(size);
    int s = MeasureSpec.getSize(size);
    if (mode == MeasureSpec.EXACTLY) {
        return s;
    } else if (mode == MeasureSpec.AT_MOST) {
        return Math.min(s, 200);
    } else {
        return 200;
    }
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.WHITE);
    canvas.drawPath(path, paint);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    x = event.getX();
    y = event.getY();
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            path.moveTo(x, y);
            break;
        case MotionEvent.ACTION_MOVE:
            path.lineTo(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            invalidate();
            break;
    }
    return true;
}

public void clear() {
    path.reset();
    invalidate();
}

public void save() {
    setDrawingCacheEnabled(false);
    setDrawingCacheEnabled(true);
    new Thread(new Runnable() {
        @Override
        public void run() {
            Bitmap drawingCache = getDrawingCache(true);
            File file = new File(getContext().getCacheDir() +  "123.png");
            FileOutputStream fileOutputStream = null;
            try {
                fileOutputStream = new FileOutputStream(file);
                drawingCache.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
                fileOutputStream.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fileOutputStream != null) {
                    try {
                        fileOutputStream.close();
                        try {
                            MediaStore.Images.Media.insertImage(getContext().getContentResolver(),
                                    file.getAbsolutePath(), "sad.png", null);
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        }
                        // 最后通知图库更新
                        getContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + file.getPath())));
                        Log.e("测试", "保存成功");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }).start();
}
}

个人博客https://myml666.github.io

目录
相关文章
|
9月前
|
数据采集 关系型数据库 MySQL
MySQL常用函数:IF、SUM等用法
本文介绍了MySQL中常用的IF、SUM等函数及其用法,通过具体示例展示了如何利用这些函数进行条件判断、数值计算以及复杂查询。同时,文章还提到了CASE WHEN语句和其他常用函数,如COUNT、AVG、MAX/MIN等,强调了它们在数据统计分析、数据清洗和报表生成中的重要性。
|
10月前
|
机器学习/深度学习 自然语言处理 计算机视觉
探索深度学习中的Transformer架构
探索深度学习中的Transformer架构
204 2
文本,wangEditor5的基本使用,开发文档地址,wangEditor5用于Vue3项目,想要使用好wangEditor项目,得看开发文档
文本,wangEditor5的基本使用,开发文档地址,wangEditor5用于Vue3项目,想要使用好wangEditor项目,得看开发文档
|
Linux 数据处理
Linux命令reset详解
`reset`命令在Linux中用于修复终端显示异常,它是`tset`的软链接。通过重置显示属性和参数,恢复终端正常状态。特点包括自动检测终端类型、多参数支持及恢复显示设置。常用参数有 `-e`, `-i`, `-k` 用于设置控制字符,`-V` 显示ncurses版本。在终端出现问题时,简单运行`reset`即可重置,定期使用可维护终端整洁。记得确保已安装ncurses库。
|
网络协议 Windows
【常用命令】netstat -ano命令图文详细说明
【常用命令】netstat -ano命令图文详细说明
953 0
|
数据采集 DataWorks 监控
DataWorks产品使用合集之在 DataWorks 中将本地数据导入至 Excel 电子表格中如何解决
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
285 0
|
机器学习/深度学习 存储 计算机视觉
基于YOLOv8深度学习的智能草莓病害检测与分割系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标检测、目标分割(2)
基于YOLOv8深度学习的智能草莓病害检测与分割系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标检测、目标分割
|
网络协议 安全 Shell
【网络协议】网络文件共享协议SMB(Server Message Block)
SMB协议允许在局域网(LAN)或广域网(WAN)上共享文件、打印机和其他资源。
1191 0
|
开发工具 git
git 新建分支,切换分支,上传到远程分支
在git中,可利用checkout命令转换分支,该命令的作用就是切换分支或恢复工作树文件,语法为“git checkout 分支名”;当参数设置为“-b”时,可以在新分支创建的同时切换分支,语法为“git checkout -b 分支名”。
|
存储 Kubernetes 监控
k8s学习-DaemonSet(模板、创建、更新、回滚、删除等)
k8s学习-DaemonSet(模板、创建、更新、回滚、删除等)
255 0

热门文章

最新文章