• Android 繪圖白板元件,有畫筆和板擦的功能 (转)


    package com.example.drawboard;
    
    import java.util.ArrayList;
    import java.util.List;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.PorterDuff;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.Rect;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    
    public class DrawBoardView extends View {
    
        //定義防止線條有鋸齒的常數
        private static final boolean GESTURE_RENDERING_ANTIALIAS = true;
        private static final boolean DITHER_FLAG = true;
    
        // 底圖 bitmap
        private Bitmap mBackgroundBitmap = null;
        // View 的整個長寬範圍
        private Rect mWholeRect;
    
        private Bitmap mBitmap = null;    // 圖層繪圖
        private Canvas mCanvas = null;    // 圖層畫布
        private Paint mDefaultPaint = new Paint();    // 空白畫筆
    
        private boolean mCapturing = true;    // 是否擷取狀態
    
        //定義繪圖的基本參數:線的 width, color
        private float mPaintWidth = 5f;
        private int mPaintColor = Color.RED;
    
        private int mPenMode = 1;    //1:為畫筆, 0:為板擦
        private Paint mPaint;
    
        private Path mPath;
    
        private List<Path> mDrawList = new ArrayList<Path>();
        private List<Paint> mPaintsList = new ArrayList<Paint>();
        private List<Rect> mRectsList = new ArrayList<Rect>();
        private int mTotalAction = 0;    // 記錄動作的次數
    
        private float mCurveStartX, mCurveStartY;    // 按下的點
        private float mX, mY;                        // 移動的點
        private float mCurveEndX, mCurveEndY;        // 放開的點
     
        private final Rect mInvalidRect = new Rect();
        private int mInvalidateExtraBorder = 10;
    
    
        // 建構子
        public DrawBoardView(Context context) {
            super(context);
            init(context);
        }
    
        // 建構子
        public DrawBoardView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }
    
        // 建構子
        public DrawBoardView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(context);
        }
    
        // 初始化
        private void init(Context context) {
            setWillNotDraw(false);
        }
    
    
        private void setPaint(Paint thePaint) {
            if (mPenMode != 0) {
                thePaint.setStrokeWidth(mPaintWidth);
                thePaint.setColor(mPaintColor);
                thePaint.setStyle(Paint.Style.STROKE);
                thePaint.setStrokeJoin(Paint.Join.ROUND);
                thePaint.setStrokeCap(Paint.Cap.ROUND);
                thePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS);
                thePaint.setDither(DITHER_FLAG);
                thePaint.setXfermode(null);
            } else { // 橡皮檫模式,先以黑色顯示範圍
                thePaint.setStrokeWidth(mPaintWidth);
                thePaint.setColor(Color.BLACK);
                thePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS);
                thePaint.setDither(DITHER_FLAG);
                thePaint.setXfermode(null);
            }
        }
    
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            this.mWholeRect = new Rect(0, 0, w, h);
    
            mBitmap = null;
            mCanvas = null;
            mBitmap = Bitmap.createBitmap(this.mWholeRect.width(), this.mWholeRect.height(), Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(mBitmap);
    
            super.onSizeChanged(w, h, oldw, oldh);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            if (mBackgroundBitmap != null) mCanvas.drawBitmap(mBackgroundBitmap, null, this.mWholeRect, null);
    
            for (int i = 0; i < mTotalAction; i++) {
                mCanvas.drawPath(mDrawList.get(i), mPaintsList.get(i));
            }
    
            if (mPath != null && mPaint != null) mCanvas.drawPath(mPath, mPaint);
    
            canvas.drawBitmap(mBitmap, 0, 0, mDefaultPaint);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mCapturing = true;
                mPaint = new Paint();
                setPaint(mPaint);
    
                mPath = new Path();
    
                touchDown(event);
                invalidate();
    
                return true;
    
            case MotionEvent.ACTION_MOVE:
                if (mCapturing) {
                    Rect rect = touchMove(event);
                    if (rect != null) {
                        invalidate(rect);
                    }
                }
    
                return true;
    
            case MotionEvent.ACTION_UP:
                touchUp(event);
                invalidate();
    
                mCapturing = false;
    
                // 先清除已復原的動作
                int totalAction = mDrawList.size();
                while (totalAction > mTotalAction) {
                    totalAction -= 1;
                    mPaintsList.remove(totalAction);
                    mRectsList.remove(totalAction);
                    mDrawList.remove(totalAction);
                }
    
                // 再加入新的動作
                mTotalAction += 1;
    
                if (mPenMode == 0) {
                    mBitmap = null;
                    mCanvas = null;
                    mBitmap = Bitmap.createBitmap(this.mWholeRect.width(), this.mWholeRect.height(), Bitmap.Config.ARGB_8888);
                    mCanvas = new Canvas(mBitmap);
    
                    // 橡皮擦屬性
                    mPaint.setColor(Color.TRANSPARENT);
                    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
                }
                mPaintsList.add(mPaint);
    
                mDrawList.add(mPath);
    
                mPaint = null;
                mPath = null;
    
                return true;
            }
    
            return false;
        }
    
        private void touchDown(MotionEvent event) {
               float x = event.getX();
               float y = event.getY();
    
               mCurveStartX = x;
               mCurveStartY = y;
               mX = x;
               mY = y;
               mCurveEndX = x;
               mCurveEndY = y;
    
               mPath.moveTo(x, y);
    
               final int border = mInvalidateExtraBorder;
               mInvalidRect.set((int) x - border, (int) y - border, (int) x + border, (int) y + border);
        }
    
        private Rect touchMove(MotionEvent event) {
               Rect areaToRefresh = null;
    
               final float x = event.getX();
               final float y = event.getY();
    
               final float previousX = mX;
               final float previousY = mY;
    
               areaToRefresh = mInvalidRect;
    
               // start with the curve end
               final int border = mInvalidateExtraBorder;
               areaToRefresh.set((int) mCurveEndX - border, (int) mCurveEndY - border,
                       (int) mCurveEndX + border, (int) mCurveEndY + border);
    
               float cX = mCurveEndX = (x + previousX) / 2;
               float cY = mCurveEndY = (y + previousY) / 2;
    
               mPath.quadTo(previousX, previousY, cX, cY);
    
               // union with the control point of the new curve
               areaToRefresh.union((int) previousX - border, (int) previousY - border,
                       (int) previousX + border, (int) previousY + border);
    
               // union with the end point of the new curve
               areaToRefresh.union((int) cX - border, (int) cY - border, (int) cX
                       + border, (int) cY + border);
    
               mX = x;
               mY = y;
    
               return areaToRefresh;
        }
    
        private void touchUp(MotionEvent event) {
               float x = event.getX();
               float y = event.getY();
    
               mCurveEndX = x;
               mCurveEndY = y;
        }
    
    
        /**
         * 復原上一動作
         * return: false 表不能再undo; true 表能繼續undo
         */
        public boolean undo() {
               int totalAction = mDrawList.size();
               if (mTotalAction > 0) {
                   mTotalAction -= 1;
    
                   mBitmap = null;
                   mCanvas = null;
                   mBitmap = Bitmap.createBitmap(this.mWholeRect.width(), this.mWholeRect.height(), Bitmap.Config.ARGB_8888);
                   mCanvas = new Canvas(mBitmap);
    
                   invalidate();
               }
    
               if (totalAction == 0 || mTotalAction <= 0) {
                   return false;
               } else {
                   return true;
               }
        }
    
    
        /**
         * 取消復原動作
         * return: false 表不能再 reUndo; true 表能繼續 reUndo
         */
        public boolean reUndo() {
               int totalAction = mDrawList.size();
               if (mTotalAction < totalAction) {
                   mTotalAction += 1;
    
                   mBitmap = null;
                   mCanvas = null;
                   mBitmap = Bitmap.createBitmap(this.mWholeRect.width(), this.mWholeRect.height(), Bitmap.Config.ARGB_8888);
                   mCanvas = new Canvas(mBitmap);
    
                   invalidate();
               }
    
               if (totalAction == 0 || mTotalAction >= totalAction) {
                   return false;
               } else {
                   return true;
               }
        }
    
    
        /**
         * 檢查可復原動作的狀態
         * return: 0 表不能再 undo,也不能再 reUndo;1 表不能再 undo,但可再 reUndo;2 表可再 undo,但不能再 reUndo;3 表可再 undo,也可再 reUndo;
         */
        public int checkUndoStatus() {
               int totalAction = mDrawList.size();
               int result = 0;
    
               if (totalAction == 0) {    //沒有任何動作資訊
                   result = 0;
               } else if (mTotalAction <= 0) {    //有動作資訊,但已「復原」至最前端
                   result = 1;
               } else if (mTotalAction >= totalAction) {    //有動作資訊,但已「取消復原」至最後端
                   result = 2;
               } else {
                   result = 3;
               }
    
               return result;
        }
    
    
        /**
         * 清除整個 View 的畫面
         */
        public void clear() {
               mBackgroundBitmap = null;
    
               mDrawList.removeAll(mDrawList);
               mPaintsList.removeAll(mPaintsList);
               mRectsList.removeAll(mRectsList);
               mTotalAction = 0;
    
               mBitmap = null;
               mCanvas = null;
               mBitmap = Bitmap.createBitmap(this.mWholeRect.width(), this.mWholeRect.height(), Bitmap.Config.ARGB_8888);
               mCanvas = new Canvas(mBitmap);
    
               invalidate();
        }
    
    
        /**
         * 設定整個 View 的畫面圖示
         */
        public void setWholeViewBitmap(Bitmap bitmap) {
            mBackgroundBitmap = bitmap;
            invalidate();
        } 
    
    
        /**
         * 設定為畫筆或板擦
         * @param penMode: 1 為畫筆, 0 為板擦
         */
        public void setPenMode(int penMode) {
            if (penMode == 0) {
                this.mPenMode = 0;
            } else {
                this.mPenMode = 1;
            }
        }
    
        /**
         * 取得是畫筆或板擦
         * @return: 1 為畫筆, 0 為板擦
         */
        public int getPenMode() {
            return this.mPenMode;
        }
    
    
        /**
         * 設定畫筆或板擦的寬度
         * @param width
         */
        public void setPaintStrokeWidth(float width) {
            this.mPaintWidth = width;
        }
    
        /**
         * 取得畫筆或板擦的寬度
         */
        public float getPaintStrokeWidth() {
            return this.mPaintWidth;
        }
    
    
        /**
         * 設定畫筆的顏色
         * @param width
         */
        public void setPaintColor(int color) {
            this.mPaintColor = color;
        }
    
        /**
         * 取得畫筆的顏色
         */
        public int getPaintColor() {
            return this.mPaintColor;
        }
    
    }

    Android 的繪圖白板元件(View)。 可當作一般的 View 元件使用。 setWholeViewBitmap(Bitmap bitmap):設定整個 View 的畫面圖示 setPenMode(int penMode):設定為畫筆或板擦 setPaintStrokeWidth(float width):設定畫筆或板擦的寬度 setPaintColor(int color):設定畫筆的顏色,话不多说自己看吧~可以直接复制代码就可以用。

  • 相关阅读:
    网络
    进程与线程
    JVM学习笔记(四)——Java内存模型和线程安全
    黑马程序员C++学习笔记
    在python中编写一个简单的关于类的情况遇到的问题(待解决)
    Python学习笔记
    项目实战
    老九学堂C++实现小游戏之小公主养成记
    C++实现经典排序算法
    C++学习代码笔记
  • 原文地址:https://www.cnblogs.com/woaixingxing/p/6490518.html
Copyright © 2020-2023  润新知