@TOC
原创 传送门
参考地址 传送门
布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/main_linlayout"
android:layout_width="match_parent"
android:layout_height="300dp"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/bt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="确定"/>
<Button
android:id="@+id/bt_pre"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="上一步"/>
<Button
android:id="@+id/bt_clear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="清空"/>
</LinearLayout>
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_gravity="center"/>
</LinearLayout>
MainActivity
package com.example.myview;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.EmbossMaskFilter;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class MainActivity extends Activity implements View.OnClickListener {
EmbossMaskFilter emboss;
BlurMaskFilter blur;
DrawView drawView;
private LinearLayout main_linlayout;
private Button bt,bt_clear,bt_pre;
private ImageView img;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
getWH();
}
//获取我们xml布局中view的宽高
private void getWH() {
// 获取创建的宽度和高度
DisplayMetrics displayMetrics = new DisplayMetrics();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics);
}
// 创建一个DrawView,该DrawView的宽度、高度与该Activity保持相同
main_linlayout = (LinearLayout)findViewById(R.id.main_linlayout);
drawView = new DrawView(this, displayMetrics.widthPixels, displayMetrics.heightPixels);
main_linlayout.addView(drawView);
drawView.requestFocus();
}
private void init() {
bt = (Button)findViewById(R.id.bt);
bt.setOnClickListener(this);
bt_clear = (Button)findViewById(R.id.bt_clear);
bt_clear.setOnClickListener(this);
bt_pre=findViewById(R.id.bt_pre);
bt_pre.setOnClickListener(this);
img = (ImageView) findViewById(R.id.img);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.bt:
Bitmap bit = drawView.getPaintBitmap();
img .setImageBitmap(bit);
break;
case R.id.bt_pre:
drawView.returnPre();
break;
case R.id.bt_clear:
drawView.clear();
break;
}
}
}
DrawView
package com.example.myview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import java.util.ArrayList;
public class DrawView extends View {
// 定义记录前一个拖动事件发生点的坐标
float preX;
float preY;
private Path path;
private Path prePath;//之前路径存储
public Paint paint = null;
// 定义一个内存中的图片,该图片将作为缓冲区
Bitmap cacheBitmap = null;
// 定义cacheBitmap上的Canvas对象
Canvas cacheCanvas = null;
ArrayList<Path> cachePath=new ArrayList<>();
public DrawView(Context context) {
super(context);
}
public DrawView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public DrawView(Context context, int width , int height) {
super(context);
cacheBitmap=Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
cacheCanvas=new Canvas();
path=new Path();
// 设置cacheCanvas将会绘制到内存中的cacheBitmap上
cacheCanvas.setBitmap(cacheBitmap);
// 设置画笔的颜色
paint = new Paint(Paint.DITHER_FLAG);
paint.setColor(Color.RED);
// 设置画笔风格
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
// 反锯齿
paint.setAntiAlias(true);
paint.setDither(true);
}
public boolean onTouchEvent(MotionEvent event){
float x=event.getX();
float y=event.getY();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
// 从前一个点绘制到当前点之后,把当前点定义成下次绘制的前一个点
path.moveTo(x, y);
preX = x;
preY = y;
break;
case MotionEvent.ACTION_MOVE:
// 从前一个点绘制到当前点之后,把当前点定义成下次绘制的前一个点
path.quadTo(preX, preY, x, y);
preX = x;
preY = y;
break;
case MotionEvent.ACTION_UP:
prePath=new Path();
prePath.addPath(path);
cachePath.add(prePath);
Log.d("绘制次数",cachePath.size()+"");
cacheCanvas.drawPath(path, paint); // ①
path.reset();
break;
}
invalidate();
// 返回true表明处理方法已经处理该事件
Log.d("onTouchEvent","onTouchEvent");
return true;
}
@Override
public void onDraw(Canvas canvas)
{
Log.d("onDraw","onDraw");
Paint bmpPaint = new Paint();
// 将cacheBitmap绘制到该View组件上
canvas.drawBitmap(cacheBitmap, 0, 0, bmpPaint); // ②
// 沿着path绘制
canvas.drawPath(path, paint);
}
public Bitmap getPaintBitmap(){
return resizeImage(cacheBitmap, 620, 780);
}
// 缩放
public static Bitmap resizeImage(Bitmap bitmap, int width, int height) {
//获取图片的宽高
int originWidth = bitmap.getWidth();
int originHeight = bitmap.getHeight();
//这里缩放我们的尺寸,缩放多少自己去定义
float scaleWidth = ((float) width) / originWidth;
float scaleHeight = ((float) height) / originHeight;
//进行缩放
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, originWidth,
originHeight, matrix, true);
return resizedBitmap;
}
//清除画板
public void clear() {
if (cacheBitmap != null) {
path.reset();
cachePath.clear();
cacheCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
invalidate();
}
}
//返回上一步绘制的情况
public void returnPre(){
path.reset();
cacheCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
invalidate();
if(cachePath.size()!=0){
for(int i=0;i<cachePath.size()-1;i++){
cacheCanvas.drawPath(cachePath.get(i),paint);
}
cachePath.remove(cachePath.size()-1);
}
Log.d("绘制次数",cachePath.size()+"");
invalidate();
}
}
传送门