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

目录
相关文章
|
4月前
|
XML API Android开发
Android 自定义View 之 圆环进度条
Android 自定义View 之 圆环进度条
|
8月前
|
Android开发
Android自定义View 水波气泡2
Android自定义View 水波气泡
|
8月前
|
Android开发
Android自定义View 水波气泡1
Android自定义View 水波气泡
Android自定义View 水波气泡1
|
Android开发 图形学
Android自定义控件(三)——贝济埃曲线与水波纹动画
我是清都山水郎,天教分付与疏狂。曾批给雨支风券,累上留云借月章。 诗万首,酒千觞。几曾着眼看侯王?玉楼金阙慵归去,且插梅花醉洛阳。
187 0
Android自定义控件(三)——贝济埃曲线与水波纹动画
|
Android开发
Android自定义View,制作饼状图带动画效果
一个简单的自定义view饼状图,加入了动画效果
125 0
Android自定义View,制作饼状图带动画效果
|
XML 前端开发 API
Android自定义View之绘制圆形头像
Android自定义View之绘制圆形头像
687 0
Android自定义View之绘制圆形头像
|
前端开发 Android开发
自定义View实例(三)----滑动刻度尺与流式布局
最近在系统学习自定义View这一块的知识,前面几篇基本都是理论知识,这篇博客着重从实战来加强对自定义View的理解与运用。实现的两种效果,分别代表自定义View与自定义ViewGroup。
1252 0
|
容器
Andrid自定义view:打造3D画廊
Andrid自定义view:打造3D画廊
166 0
Andrid自定义view:打造3D画廊
|
前端开发 Android开发
01.自定义View(ArcView弧形进度条)
开始重新学习一下自定义View的相关知识,借鉴了一些网上的文章,目前在跟这位博主学习,大家可以关注一下 作者:红橙Darren 链接:https://www.
1086 0
|
前端开发
02.自定义View(RippleTextView可颜色渐变的TextView)
感谢红橙Darren博主 package com.rzm.commonlibrary.views; import android.content.Context; import android.
971 0

热门文章

最新文章