xml的布局文件
<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">
<SurfaceView
android:id="@+id/draw"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="10" />
<SeekBar
android:id="@+id/seek"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/blue"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="蓝色" />
<Button
android:id="@+id/green"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="绿色" />
<Button
android:id="@+id/red"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="红色" />
<Button
android:id="@+id/black"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="黑色" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<Button
android:id="@+id/previous"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="上一张" />
<Button
android:id="@+id/next"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="下一张" />
</LinearLayout>
</LinearLayout>
Activity中的代码
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, View.OnClickListener, View.OnTouchListener, SeekBar.OnSeekBarChangeListener {
/**
* 画布
*/
private SurfaceView mDraw;
/**
* 切换上一张下一张画布
*/
private Button mPrevious;
private Button mNext;
/**
* 拖动进度条
*/
private SeekBar mSeek;
/**
* 切换颜色
*/
private Button mBlue;
private Button mGreen;
private Button mRed;
private Button mBlack;
/**
* 存储当前选择颜色
*/
private int color;
/**
* 存储画布
*/
List<PathEntity> pathEntities;
/**
* 存储一张画布上所有路径
*/
List<List<PathEntity>> lists;
private int index = 0;
private int width;
@SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findView();
SurfaceHolder surfaceHolder = mDraw.getHolder();
lists = new ArrayList<>();
pathEntities = new ArrayList<>();
pathEntities.add(new PathEntity(new Path(), Color.BLACK, new Paint()));
lists.add(pathEntities);
surfaceHolder.addCallback(this);
mDraw.setOnTouchListener(this);
mNext.setOnClickListener(this);
mPrevious.setOnClickListener(this);
mSeek.setOnSeekBarChangeListener(this);
mBlue.setOnClickListener(this);
mBlack.setOnClickListener(this);
mGreen.setOnClickListener(this);
mRed.setOnClickListener(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// 子线程绘制
new Thread() {
@Override
public void run() {
while (true) {
Canvas canvas = holder.lockCanvas();
// 页面被关闭获取不到canvas时停止绘制
if (canvas == null) {
break;
}
// 绘制底色
canvas.drawColor(Color.WHITE);
List<PathEntity> pathEntities = lists.get(index);
// 绘制已有的路径
for (int i = 0; i < pathEntities.size(); i++) {
canvas.drawPath(pathEntities.get(i).getPath(), pathEntities.get(i).getPaint());
}
holder.unlockCanvasAndPost(canvas);
}
}
}.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.previous:
// 切换上一张画布
if (index - 1 >= 0)
index--;
break;
case R.id.next:
// 切换下一张画布
if (lists.size() == index + 1) {
pathEntities = new ArrayList<>();
pathEntities.add(new PathEntity(new Path(), Color.BLACK, new Paint()));
lists.add(pathEntities);
}
index++;
break;
//更改颜色
case R.id.blue:
color = Color.BLUE;
break;
case R.id.red:
color = Color.RED;
break;
case R.id.green:
color = Color.GREEN;
break;
case R.id.black:
color = Color.BLACK;
break;
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// 获取x、y轴位置
float x = event.getX();
float y = event.getY();
// 获取当前这张画板的内容
List<PathEntity> pathEntities = lists.get(index);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 创建新的路径画笔颜色
pathEntities.add(new PathEntity(new Path(), color, new Paint(), width));
pathEntities.get(pathEntities.size() - 1).getPath().moveTo(x, y);
break;
case MotionEvent.ACTION_MOVE:
// 连接路径
pathEntities.get(pathEntities.size() - 1).getPath().lineTo(x, y);
break;
}
return true;
}
/**
* 查找控件
*/
private void findView() {
mDraw = findViewById(R.id.draw);
mPrevious = findViewById(R.id.previous);
mNext = findViewById(R.id.next);
mSeek = findViewById(R.id.seek);
mBlue = findViewById(R.id.blue);
mGreen = findViewById(R.id.green);
mRed = findViewById(R.id.red);
mBlack = findViewById(R.id.black);
}
/**
* 拖动进度条监听回调 更改画笔宽度
*/
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
width = progress;
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
其中使用到的Bean类
public class PathEntity {
private Path path;
private int color;
private Paint paint;
private int width;
public PathEntity(Path path, int color, Paint paint, int width) {
this.path = path;
this.color = color;
this.paint = paint;
this.width = width;
initPaint();
}
public Path getPath() {
return path;
}
public Paint getPaint() {
return paint;
}
public PathEntity(Path path, int color, Paint paint) {
this.path = path;
this.color = color;
this.paint = paint;
initPaint();
}
private void initPaint() {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(width);
paint.setAntiAlias(true);
paint.setColor(color);
}
}