Android 笔记 SurfaceView实现涂鸦,轨迹重新绘制

时间:2022-08-29 21:35:33

实现涂鸦,点击绘制,将涂鸦过程再绘制一次。
自定义SurfaceView

package com.bencoo.kme.view;

import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class DrawLine extends SurfaceView implements SurfaceHolder.Callback,Runnable {
    private float currentX;
    private float currentY;
    private Point currentPoint;
    private Path mPath;// 轨迹
    public List<Point> point = new ArrayList<Point>();//存储每个轨迹点
    private int index;//点索引
    private SurfaceHolder holder;
    private Thread mThread;//线程
    /** * @description 画笔 * @date 2016-04-26 */
    private Paint paint;

    public DrawLine(Context context) {
        super(context);
        init();
    }

    public DrawLine(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public DrawLine(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    /** * @description 初始化 * @date 2016-04-27 */
    private void init() {
        holder = getHolder();
        holder.addCallback(this);
        mPath = new Path();
        paint = new Paint();
        paint.setAntiAlias(true);// 去除锯齿
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);// 笔宽
        paint.setColor(Color.BLUE);// 颜色
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        float stopX = event.getX();
        float stopY = event.getY();
        Point pointx = new Point((int) stopX, (int) stopY);
        switch (action) {

        case MotionEvent.ACTION_DOWN:// 按下
            mPath.reset();
            currentX = event.getX();
            currentY = event.getY();
            currentPoint = new Point((int) currentX, (int) currentY);
            mPath.moveTo(currentX, currentY);
            point.add(pointx);
            break;

        case MotionEvent.ACTION_MOVE:
            point.add(pointx);
            float sX = event.getX();
            float sY = event.getY();
            System.out.println(sX + "---" + sY);
            mPath.lineTo(sX, sY);
            Point p=new Point((int)sX, (int)sY);
            draw();
            break;
        case MotionEvent.ACTION_UP:
            point.add(pointx);
            break;
        }
        invalidate();
        return true;
    }


    public Path getPath() {
        return mPath;
    }

    public List<Point> getPoints() {
        return point;

    }

    public Point getCurrentPoint() {
        return currentPoint;

    }

    /** * @description 清除 * @date 2016-04-26 */
    public void clear() {
        mPath.reset();// 去除路径
        invalidate();// 刷新
    }
    /** * @descriptionb 开始绘制 * @date */
    public void start() {
        mThread=new Thread(this);
        mThread.start();
    }
    /** * @descriptionb 停止线程 * @date */
    public void stop(){
        if(mThread!=null){
            mThread.interrupt();
            try {
                mThread.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
    /** * @descriptionb 绘制方法 * @date */
    private void draw() {
        Canvas canvas = holder.lockCanvas();
        Paint pa = new Paint();
        pa.setAntiAlias(true);
        pa.setColor(Color.RED);
        pa.setStyle(Paint.Style.STROKE);
        pa.setStrokeWidth(5);
        canvas.drawColor(Color.WHITE);
        canvas.drawPath(mPath, pa);
        System.out.println("画" + index);
        // 解锁画布
        getHolder().unlockCanvasAndPost(canvas);

    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
        Canvas canvas=holder.lockCanvas();
        canvas.drawColor(Color.WHITE);
        holder.unlockCanvasAndPost(canvas);
    }

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        if(mThread!=null){
            mThread.interrupt();
            try {
                mThread.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
    /** * @description 重绘轨迹 */
    @Override
    public void run() {
        Canvas canvas=null;
        Path path=new Path();
        path.moveTo(currentX, currentY);
        while (index<point.size()) {
            Point p=point.get(index);
            canvas=holder.lockCanvas();
            canvas.drawColor(Color.WHITE);
            path.lineTo(p.x, p.y);
            canvas.drawPath(path, paint);
            index++;
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            holder.unlockCanvasAndPost(canvas);
        }

    }

}

Activity代码

package com.bencoo.kme.activity;

import com.bencoo.kme.R;
import com.bencoo.kme.view.DrawLine;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class TestActivity extends Activity{
    private Button play;
    private DrawLine drawline;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        init();
    }
    private void init(){
        play=(Button) this.findViewById(R.id.bt_play);
        drawline=(DrawLine) this.findViewById(R.id.drawline);
        play.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                drawline.start();//启动重绘线程
            }
        });
    }
}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" >
    <Button android:id="@+id/bt_play" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="绘制"/>
    <com.bencoo.kme.view.DrawLine android:id="@+id/drawline" android:layout_width="match_parent" android:layout_height="match_parent"/>
</LinearLayout>