自定义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

目录
相关文章
|
容器
自定义View
自定义View 画一个实心圆 效果图 创建attrs.xml文件 初始化样式属性 支持Padding属性 支持wrap_content属性 布局文件中的应用 画一个带外圆环的圆 效果图 创建attrs.xml文件 初始化样式属性 内圆与外圆环的绘制 布局文件中的应用 画一个外圆环可根据数值变动的圆 效果图 创建attrs.xml文件 初始化样式属性 绘制View 提供方法修改样式 布局文件中的应用
110 0
自定义View
|
XML 前端开发 API
Android自定义View之绘制圆形头像
Android自定义View之绘制圆形头像
753 0
Android自定义View之绘制圆形头像
|
容器
Andrid自定义view:打造3D画廊
Andrid自定义view:打造3D画廊
201 0
Andrid自定义view:打造3D画廊
|
前端开发
自定义View -简单的 SwitchView
前言 实现一个简单的滑动开发,效果图如下: switchView完整版本 分析 平分整个View为两份 平分VIew 测量字体的高度和宽度,确定左右View的文字的位置并进行绘制 确定字体的位置和绘制 绘制...
1033 0
|
XML Android开发 数据格式
3.6 自定义View (3.6.2)
本文对应项目的码云地址:https://gitee.com/wanchuanxy/AndroidHeroesTest/tree/master/3/SystemWidget 3.6.2 创建复合控件 创建复合控件可以很好地创建出具有重用功能的控件集合。
660 0
|
前端开发 Android开发
3.6 自定义View (3.6.1)
本文对应项目的码云地址:https://gitee.com/wanchuanxy/AndroidHeroesTest/tree/master/3/SystemWidget Android给我们提供了丰富的组件库来创建丰富的UI效果,同时也提供了非常方便的拓展方法。
739 0
|
前端开发 Android开发
01.自定义View(ArcView弧形进度条)
开始重新学习一下自定义View的相关知识,借鉴了一些网上的文章,目前在跟这位博主学习,大家可以关注一下 作者:红橙Darren 链接:https://www.
1124 0
|
前端开发
02.自定义View(RippleTextView可颜色渐变的TextView)
感谢红橙Darren博主 package com.rzm.commonlibrary.views; import android.content.Context; import android.
1021 0
|
XML 数据格式
自定义View(一)
一、初探 大家都知道自定义view需要重写onMeasure和onDraw两个方法,这里我们在讲这两个方法前首先看看什么时候走这两个方法,这里只是大致讲讲方便理解,详细的之后会说。
754 0