自定义view-(你画我猜)画板

上次在微信小程序上看到了你画我猜的那个小程序,就寻思着自己也做一个这样的界面,话不多说,先看效果图


里面包含了3个主要的自定义view,分别是画板,宽度选择器,颜色选择器,这三个view互相关联

开始上代码吧

1.先看我的页面布局

<?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"
    tools:context="com.rxd.drawandguess.MainActivity"
    android:orientation="vertical">

    <com.rxd.drawandguess.DrawView
        android:id="@+id/draw_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:orientation="vertical"
        android:background="#ddd">
        
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="75dp"
            android:orientation="horizontal">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:text="粗细"
                android:textSize="20sp"
                android:gravity="center"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="10dp"/>

            <com.rxd.drawandguess.StrokeWidthChooseView
                android:id="@+id/strokeWidthChooseView"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="match_parent" />

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="center_vertical"
                android:orientation="horizontal"
                android:layout_marginLeft="10dp">

                <ImageButton
                    android:id="@+id/ib_back"
                    android:layout_width="48dp"
                    android:layout_height="48dp"
                    android:src="@mipmap/back"
                    android:scaleType="centerCrop"/>

                <ImageButton
                    android:id="@+id/ib_eraser"
                    android:layout_width="wrap_content"
                    android:layout_height="48dp"
                    android:scaleType="centerCrop"
                    android:src="@mipmap/rubbish" />

                <ImageButton
                    android:id="@+id/ib_clear"
                    android:layout_width="48dp"
                    android:layout_height="48dp"
                    android:src="@mipmap/clear"
                    android:scaleType="centerCrop"/>

                </LinearLayout>

            
            </LinearLayout>
        
        <com.rxd.drawandguess.ColorHorizontalScrollView
            android:id="@+id/colorHorizontalScrollView"
            android:layout_width="match_parent"
            android:layout_height="75dp"></com.rxd.drawandguess.ColorHorizontalScrollView>

    </LinearLayout>

</LinearLayout>

2.宽度选择器的view

我们需要设置一个枚举状态来判断当前画板是处于什么时期,所以我们在Drawview中设置了一个枚举

public enum State{
        PEN,
        ERASER
    }

这两个状态分别是画笔和橡皮擦。

我们还需要一个状态来判断当前选中的是哪个

private int mCurrentIndex = 0;

然后再ondraw事件中判断当前是什么画笔状态,当前按下的是第几个

for (int i = 0; i < rectList.size(); i++){
            Rect rect = rectList.get(i);
            float radius = widthArray[i];
            switch (mCurrentState){
                case PEN:
                    mChoosePaint.setColor(Color.WHITE);
                    if (mCurrentIndex == i){
                        canvas.drawCircle(rect.centerX(), rect.centerY(), radius + 10, mChoosePaint);
                    }
                    canvas.drawCircle(rect.centerX(), rect.centerY(), radius, mPaint);
                    break;
                case ERASER:
                    mChoosePaint.setColor(Color.BLACK);
                    if (mCurrentIndex == i){
                        canvas.drawCircle(rect.centerX(), rect.centerY(), radius + 10, mChoosePaint);
                    }
                    canvas.drawCircle(rect.centerX(), rect.centerY(), radius, mWhitePaint);
                    break;
            }

        }

剩下的就是处理点击事件啦,下面是完整的代码

public class StrokeWidthChooseView extends View {

    private Paint mPaint;
    private Paint mChoosePaint;
    private Paint mWhitePaint;
    private int mWidth;
    private int mHeight;
    private int[] widthArray = new int[]{10, 20, 30, 40};
    private List<Rect> rectList;
    private List<Region> regionList;
    private int mPaintColor = Color.parseColor("#000000");
    private int mCurrentIndex = 0;
    private int downX, downY;
    private DrawView drawView;
    private DrawView.State mCurrentState = DrawView.State.PEN;

    public StrokeWidthChooseView(Context context) {
        this(context, null);
    }

    public StrokeWidthChooseView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    private void initPaint() {
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);

        mChoosePaint = new Paint();
        mChoosePaint.setAntiAlias(true);
        mChoosePaint.setStyle(Paint.Style.FILL);


        mWhitePaint = new Paint();
        mWhitePaint.setAntiAlias(true);
        mWhitePaint.setStyle(Paint.Style.FILL);
        mWhitePaint.setColor(Color.WHITE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
        rectList = new ArrayList<>();
        regionList = new ArrayList<>();
        int perWidth = mWidth / widthArray.length;
        Rect rect;
        Region region;
        Rect chooseRect;
        for (int i = 0; i < widthArray.length; i++){
            rect = new Rect(perWidth * i + perWidth / 2 - widthArray[i],
                                mHeight / 2 - widthArray[i],
                                perWidth * i + perWidth / 2 + widthArray[i],
                                mHeight / 2 + widthArray[i]);
            chooseRect = new Rect(perWidth * i + perWidth / 2 - widthArray[widthArray.length - 1],
                                  mHeight / 2 - widthArray[widthArray.length - 1],
                                  perWidth * i + perWidth / 2 + widthArray[widthArray.length - 1],
                                  mHeight / 2 + widthArray[widthArray.length - 1]);
            region = new Region(chooseRect);
            rectList.add(rect);
            regionList.add(region);
        }
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(mPaintColor);

        for (int i = 0; i < rectList.size(); i++){
            Rect rect = rectList.get(i);
            float radius = widthArray[i];
            switch (mCurrentState){
                case PEN:
                    mChoosePaint.setColor(Color.WHITE);
                    if (mCurrentIndex == i){
                        canvas.drawCircle(rect.centerX(), rect.centerY(), radius + 10, mChoosePaint);
                    }
                    canvas.drawCircle(rect.centerX(), rect.centerY(), radius, mPaint);
                    break;
                case ERASER:
                    mChoosePaint.setColor(Color.BLACK);
                    if (mCurrentIndex == i){
                        canvas.drawCircle(rect.centerX(), rect.centerY(), radius + 10, mChoosePaint);
                    }
                    canvas.drawCircle(rect.centerX(), rect.centerY(), radius, mWhitePaint);
                    break;
            }

        }

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                downX = x;
                downY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                for (int i = 0; i < regionList.size(); i++){
                    Region region = regionList.get(i);
                    if (region.contains(x, y) && region.contains(downX, downY)){
                        mCurrentIndex = i;
                        switch (mCurrentState){
                            case PEN:
                                drawView.setmStrokeWidth(widthArray[i]);
                                break;
                            case ERASER:
                                drawView.setmEraserWidth(widthArray[i]);
                                break;
                        }

                    }
                }
                invalidate();
                break;
        }
        return true;
    }

    public void setWidthArray(int[] widthArray) {
        this.widthArray = widthArray;
    }

    public void setmPaintColor(int mPaintColor) {
        this.mPaintColor = mPaintColor;
        drawView.setmPaintColor(mPaintColor);
        invalidate();
    }

    public void setDrawView(DrawView drawView) {
        this.drawView = drawView;
        drawView.setmStrokeWidth(widthArray[0]);
        drawView.setmEraserWidth(widthArray[0]);
    }

    public void setmCurrentState(DrawView.State mCurrentState) {
        this.mCurrentState = mCurrentState;
        invalidate();
        if (mCurrentState == DrawView.State.ERASER){
            drawView.setmEraserWidth(widthArray[mCurrentIndex]);
        }else{
            drawView.setmStrokeWidth(widthArray[mCurrentIndex]);
        }
    }
}

3.颜色选择view

这个自定义view其实就是一个类似HorizontalScrollView的效果

我们需要一组颜色的数组,以及存放每个正方形的数组

@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        Rect rect;
        for (int i = 0; i < colors.length; i++){
            int centerX = 20 * i + radius * 2 * i + radius;
            int centerY = h / 2;
            rect = new Rect(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
            rectList.add(rect);
        }
    }

然后再ondraw中将所有正方形绘制出来,当然,选中的颜色的正方形下方有一个长方形

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Rect rect;
        Rect chooseRect;
        switch (mCurrentState){
            case ERASER:
                for (int i = 0; i < rectList.size(); i++){
                    mPaint.setColor(colors[i]);
                    rect = rectList.get(i);
                    canvas.drawRect(rect, mPaint);
                }
                break;
            case PEN:
                for (int i = 0; i < rectList.size(); i++){
                    mPaint.setColor(colors[i]);
                    rect = rectList.get(i);
                    if (currentIndex == i){
                        chooseRect = new Rect(rect.left, rect.bottom - 10, rect.right, rect.bottom);
                        rect = new Rect(rect.left, rect.top - 30, rect.right, rect.bottom - 30);
                        canvas.drawRect(chooseRect, mPaint);
                        canvas.drawRect(rect, mPaint);
                    }else{
                        canvas.drawRect(rect, mPaint);
                    }

                }
                break;
        }
    }

最后在处理点击事件的时候,我发现我的手机在不管怎么按,都会有move事件,所有我做了一些判断,判断move的长度是否大于10

下面是完整代码

public class ColorHorizontalScrollView extends View{

    private Paint mPaint;
    private int radius = 50;
    private List<Rect> rectList;
    private List<Region> regionList;
    private float startX, startY;
    private float dx, dy;
    private StrokeWidthChooseView strokeWidthChooseView;
    private int currentIndex = -1;
    private DrawView.State mCurrentState = DrawView.State.PEN;
    private onStateChnaged onStateChnagedListener;
    private int[] colors = new int[]{
            Color.parseColor("#fd039d"),
            Color.parseColor("#ff4d3f"),
            Color.parseColor("#fda602"),
            Color.parseColor("#fff001"),
            Color.parseColor("#000000"),
            Color.parseColor("#00b181"),
            Color.parseColor("#004bfe"),
            Color.parseColor("#2c6281"),
            Color.parseColor("#4e4c61"),
            Color.parseColor("#edd93f"),
            Color.parseColor("#666666"),
            Color.parseColor("#66b502"),
            Color.parseColor("#66fecb"),
            Color.parseColor("#03c1fe"),
            Color.parseColor("#966b59"),
            Color.parseColor("#fda7a4"),
            Color.parseColor("#f42728"),
            Color.parseColor("#2c6281"),
            Color.parseColor("#4e4c61"),
            Color.parseColor("#edd93f"),
            Color.parseColor("#666666"),
            Color.parseColor("#c9c9c9"),
            Color.parseColor("#8efbf6"),
            Color.parseColor("#78d1b8"),
            Color.parseColor("#bb18fd"),
            Color.parseColor("#ffffcc"),
            Color.parseColor("#fdcdb7"),
            Color.parseColor("#993300"),
    };

    public ColorHorizontalScrollView(Context context) {
        this(context, null);
    }

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

    private void init(){
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.FILL);

        rectList = new ArrayList<>();
        regionList = new ArrayList<>();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        Rect rect;
        for (int i = 0; i < colors.length; i++){
            int centerX = 20 * i + radius * 2 * i + radius;
            int centerY = h / 2;
            rect = new Rect(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
            rectList.add(rect);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Rect rect;
        Rect chooseRect;
        switch (mCurrentState){
            case ERASER:
                for (int i = 0; i < rectList.size(); i++){
                    mPaint.setColor(colors[i]);
                    rect = rectList.get(i);
                    canvas.drawRect(rect, mPaint);
                }
                break;
            case PEN:
                for (int i = 0; i < rectList.size(); i++){
                    mPaint.setColor(colors[i]);
                    rect = rectList.get(i);
                    if (currentIndex == i){
                        chooseRect = new Rect(rect.left, rect.bottom - 10, rect.right, rect.bottom);
                        rect = new Rect(rect.left, rect.top - 30, rect.right, rect.bottom - 30);
                        canvas.drawRect(chooseRect, mPaint);
                        canvas.drawRect(rect, mPaint);
                    }else{
                        canvas.drawRect(rect, mPaint);
                    }

                }
                break;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.d("TAG", "ACTION_DOWN");
                startX = event.getX();
                startY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                Log.d("TAG", "ACTION_MOVE");
                dx = event.getX() - startX;
                dy = event.getY() - startY;
                if (Math.abs(dx) -  Math.abs(dy) > ViewConfiguration.getTouchSlop()){
                    if (getScrollX() + (-dx) < 0 || getScrollX() + (-dx) > getWidth()){
                        return true;
                    }
                    this.scrollBy((int) -dx, 0);
                    startX = event.getX();
                    startY = event.getY();
                }
                break;
            case MotionEvent.ACTION_UP:
                if (Math.abs(dx) <= 10 && Math.abs(dy) <= 10){
                    for (int i = 0; i < rectList.size(); i++){
                        if (rectList.get(i).contains((int) startX + getScrollX(), (int) startY + getScrollY())){
                            Log.d("TAG", "有包含的");
                            Rect rect;
                            rectList.clear();
                            for (int j = 0; j < colors.length; j++){
                                int centerX = 20 * j + radius * 2 * j + radius;
                                int centerY = getHeight() / 2;
                                rect = new Rect(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
                                rectList.add(rect);
                            }
                            currentIndex = i;
                            onStateChnagedListener.onPen();
                            strokeWidthChooseView.setmPaintColor(colors[i]);
                            invalidate();
                        }
                    }
                }
                startX = 0;
                startY = 0;
                dx = 0;
                dy = 0;
                break;
        }
        return true;
    }

    public void setStrokeWidthChooseView(StrokeWidthChooseView strokeWidthChooseView) {
        this.strokeWidthChooseView = strokeWidthChooseView;
    }

    public void setmCurrentState(DrawView.State mCurrentState) {
        this.mCurrentState = mCurrentState;
        invalidate();
    }

    public interface onStateChnaged{
        void onPen();
    }

    public void setOnStateChnagedListener(onStateChnaged onStateChnagedListener) {
        this.onStateChnagedListener = onStateChnagedListener;
    }
}

4.最关键的画板的view

先说一下思路,绘制主要是通过path来完成的,橡皮擦则是利用PorterDuffXfermode来完成的,关于这个,大家就自行百度一下吧,我这里就不介绍了,返回的功能就相对比较复杂了,我没有在path类中找到合适的api,如果大家有的话,可以告诉我一声,谢谢啦。我现在的做法就是将每一步绘制的时候的画笔路径,状态,颜色和宽度都存储到一个stack中,每按一下返回,就弹出一个数据,然后利用剩下的path重绘界面,下面是完整代码

public class DrawView extends View{

    private Paint drawPaint;
    private Paint eraserPaint;
    private Paint backPaint;
    private Path mPath;
    private float mx, my;
    private Canvas mCanvas;
    private static final float TOUCH_TOLERANCE = 4;
    private Bitmap cacheBitmap;
    public enum State{
        PEN,
        ERASER
    }
    private State mCurrentState = State.PEN;
    private int mStrokeWidth;
    private int mEraserWidth;
    private int mPaintColor = Color.BLACK;
    private Stack<Path> paths;
    private Stack<Integer> states;
    private Stack<Integer> colors;
    private Stack<Float> widths;


    public DrawView(Context context) {
        this(context, null);
    }

    public DrawView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init(){
        drawPaint = new Paint();
        drawPaint.setAntiAlias(true);
        drawPaint.setStyle(Paint.Style.STROKE);
        drawPaint.setStrokeCap(Paint.Cap.ROUND);
        drawPaint.setColor(mPaintColor);
        drawPaint.setStrokeJoin(Paint.Join.ROUND);

        backPaint = new Paint();
        backPaint.setColor(Color.WHITE);
        backPaint.setAntiAlias(true);


        eraserPaint = new Paint();
        eraserPaint.setAlpha(0);
        eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        //eraserPaint.setColor(Color.RED);
        eraserPaint.setAntiAlias(true);
        eraserPaint.setDither(true);
        eraserPaint.setStyle(Paint.Style.STROKE);
        eraserPaint.setStrokeJoin(Paint.Join.ROUND);

        mPath = new Path();
        paths = new Stack<>();
        states = new Stack<>();
        colors = new Stack<>();
        widths = new Stack<>();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        cacheBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(cacheBitmap);
        mCanvas.drawColor(Color.TRANSPARENT);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(cacheBitmap, 0, 0, backPaint);
    }



    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                TouchDown(x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                TouchMove(x, y);
                break;
            case MotionEvent.ACTION_UP:
                TouchUp();
                break;
        }
        invalidate();
        return true;
    }

    private void TouchUp() {
        mPath.lineTo(mx, my);
        drawPath();
        Path path = new Path();
        path.set(mPath);
        paths.push(path);
        if (mCurrentState == State.PEN){
            states.push(0);
            int color = drawPaint.getColor();
            colors.push(color);
            widths.push(drawPaint.getStrokeWidth());
        }else{
            states.push(1);
            int color = eraserPaint.getColor();
            colors.push(color);
            widths.push(eraserPaint.getStrokeWidth());
        }

    }

    private void TouchMove(float x, float y) {
        float dx = Math.abs(x - mx);
        float dy = Math.abs(y - my);
        if (dx >=  TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE){
            mPath.quadTo(mx, my, (x + mx) / 2, (y + my) / 2);
            mx = x;
            my = y;
            drawPath();
        }
    }

    private void TouchDown(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mx = x;
        my = y;
        drawPath();
    }

    public void setCurrentState(State state) {
       this.mCurrentState = state;
       invalidate();
    }

    public State getmCurrentState() {
        return mCurrentState;
    }

    private void drawPath(){
        switch (mCurrentState){
            case PEN:
                mCanvas.drawPath(mPath, drawPaint);
                break;
            case ERASER:
                mCanvas.drawPath(mPath, eraserPaint);
                break;
        }
    }

    public void setmStrokeWidth(int mStrokeWidth) {
        this.mStrokeWidth = mStrokeWidth;
        drawPaint.setStrokeWidth(mStrokeWidth);
    }

    public void setmPaintColor(int mPaintColor) {
        this.mPaintColor = mPaintColor;
        drawPaint.setColor(mPaintColor);
    }

    public void clearPath(){
        mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        mPath.reset();
        paths.clear();
        states.clear();
        colors.clear();
        widths.clear();
        invalidate();
    }

    public void back(){
        if (!paths.empty()){
            mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
            mPath.reset();
            paths.pop();
            states.pop();
            colors.pop();
            widths.pop();

            Log.d("TAG", "size ==> " + paths.size());
            Paint paint1 = new Paint();
            Paint paint2 = new Paint();
            paint1.setAntiAlias(true);
            paint1.setStyle(Paint.Style.STROKE);
            paint1.setStrokeCap(Paint.Cap.ROUND);
            paint1.setStrokeJoin(Paint.Join.ROUND);
            paint2.setAlpha(0);
            paint2.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
            paint2.setAntiAlias(true);
            paint2.setDither(true);
            paint2.setStyle(Paint.Style.STROKE);
            paint2.setStrokeJoin(Paint.Join.ROUND);

            for (int i = 0; i < paths.size(); i++){
                Log.d("TAG", "empty --> " + paths.get(i).isEmpty());
                if (states.get(i) == 0){
                    paint1.setColor(colors.get(i));
                    paint1.setStrokeWidth(widths.get(i));
                    mCanvas.drawPath(paths.get(i), paint1);
                }else{
                    paint2.setColor(colors.get(i));
                    paint2.setStrokeWidth(widths.get(i));
                    mCanvas.drawPath(paths.get(i), paint2);
                }
            }
            invalidate();
        }
    }

    public void setmEraserWidth(int mEraserWidth) {
        this.mEraserWidth = mEraserWidth;
        eraserPaint.setStrokeWidth(mEraserWidth);
    }

}

5.activity

在使用之前,我们需要将这三个view互相关联起来

 strokeWidthChooseView.setDrawView(drawView);
        colorHorizontalScrollView.setStrokeWidthChooseView(strokeWidthChooseView);
        colorHorizontalScrollView.setOnStateChnagedListener(this);

下面是activity中的完整代码

public class MainActivity extends AppCompatActivity implements ColorHorizontalScrollView.onStateChnaged {

    private DrawView drawView;
    private ColorHorizontalScrollView colorHorizontalScrollView;
    private StrokeWidthChooseView strokeWidthChooseView;
    private ImageButton ibBack;
    private ImageButton ibEraser;
    private ImageButton ibClear;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        initListener();
    }

    private void initView(){
        drawView = findViewById(R.id.draw_view);
        colorHorizontalScrollView = findViewById(R.id.colorHorizontalScrollView);
        strokeWidthChooseView = findViewById(R.id.strokeWidthChooseView);
        ibBack = findViewById(R.id.ib_back);
        ibEraser = findViewById(R.id.ib_eraser);
        ibClear = findViewById(R.id.ib_clear);

        strokeWidthChooseView.setDrawView(drawView);
        colorHorizontalScrollView.setStrokeWidthChooseView(strokeWidthChooseView);
        colorHorizontalScrollView.setOnStateChnagedListener(this);
    }

    private void initListener(){
        ibBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                drawView.back();
            }
        });

        ibEraser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (drawView.getmCurrentState() == DrawView.State.ERASER){
                    becomePen();
                }else if (drawView.getmCurrentState() == DrawView.State.PEN){
                    becomeEraser();
                }
            }
        });

        ibClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new AlertDialog.Builder(MainActivity.this)
                        .setTitle("提示")
                        .setMessage("确定清空画布嘛")
                        .setNegativeButton("不行", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                            }
                        })
                        .setPositiveButton("好的", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                drawView.clearPath();
                            }
                        }).create().show();
            }
        });
    }

    @Override
    public void onPen() {
        becomePen();
    }

    private void becomePen(){
        drawView.setCurrentState(DrawView.State.PEN);
        strokeWidthChooseView.setmCurrentState(DrawView.State.PEN);
        colorHorizontalScrollView.setmCurrentState(DrawView.State.PEN);
        ibEraser.setImageResource(R.mipmap.rubbish);
    }

    private void becomeEraser(){
        drawView.setCurrentState(DrawView.State.ERASER);
        strokeWidthChooseView.setmCurrentState(DrawView.State.ERASER);
        colorHorizontalScrollView.setmCurrentState(DrawView.State.ERASER);
        ibEraser.setImageResource(R.mipmap.pen);
    }

}

可能还会很多问题,请大家多多指正。。。

附上下载地址:https://download.csdn.net/download/wagg1993323/10290791

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值