1
public class Drawing extends View {
private Paint mPaint, mBitmapPaint;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;

private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;

private int color, size, state;

private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
private ArrayList<Integer> colors = new ArrayList<Integer>();
private ArrayList<Integer> sizes = new ArrayList<Integer>();

public Drawing(Context c) {
    super(c);
}

public Drawing(Context c, int width, int height, int size, int color,
        int state) {
    super(c);

    mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    mCanvas = new Canvas(mBitmap);
    mPath = new Path();

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);

    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    mBitmapPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));

    setColor(color);
    setSize(size);
    setState(state);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
}

@Override
protected void onDraw(Canvas canvas) {
    if (state == 0) {
        canvas.drawColor(Color.TRANSPARENT);
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
        mPaint.setColor(Color.TRANSPARENT);
    } else {
        for (int i = 0; i < paths.size(); i++) {
            mPaint.setColor(colors.get(i));
            mPaint.setStrokeWidth(sizes.get(i));
            canvas.drawPath(paths.get(i), mPaint);
        }

        mPaint.setColor(color);
        mPaint.setStrokeWidth(size);
    }
    canvas.drawPath(mPath, mPaint);

}

public void setColor(int color) {
    this.color = color;
}

public void setSize(int size) {
    this.size = size;
}

public void setState(int state) {
    this.state = state;
    if (state == 0)
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    else
        mPaint.setXfermode(null);
}

public void onClickUndo() {
    if (paths.size() > 0) {
        undonePaths.add(paths.remove(paths.size() - 1));
        sizes.remove(sizes.size() - 1);
        colors.remove(colors.size() - 1);
        invalidate();
    }
}

private void touch_start(float x, float y) {
    undonePaths.clear();
    mPath.reset();
    mPath.moveTo(x, y);
    mX = x;
    mY = y;
}

private void touch_move(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;
    }
}

private void touch_up() {
    mPath.lineTo(mX, mY);
    mCanvas.drawPath(mPath, mPaint);

    if (state == 0)
        colors.add(Color.TRANSPARENT);
    else
        colors.add(color);
    sizes.add(size);
    paths.add(mPath);
    mPath = new Path();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        touch_start(x, y);
        invalidate();
        break;
    case MotionEvent.ACTION_MOVE:
        touch_move(x, y);
        invalidate();
        break;
    case MotionEvent.ACTION_UP:
        touch_up();
        invalidate();
        break;
    }
    return true;
}
}

例如,我的第一条路径是黑色。然后我更改为橡皮擦模式并包裹路径的中间部分。之后,我切换回绘图。正确的是以前的路径会改变,但被删除的部分正在恢复。这意味着我无法编辑路径。

还有其他方法可以实现这一目标吗?

4

0 回答 0