在android中的绘图画布中撤消

时间:2015-02-02 08:03:35

标签: android android-layout canvas android-bitmap

我正在研究android中的撤消操作。问题是,目前没有设置位图,我无法绘制它。

这是我的代码,它是从扩展的imageview中提取的:

private ArrayList<Path> paths = new ArrayList<Path>();
private Path mPath;

public ScaleImageView(Context context) {
    super(context);
    sharedConstructing(context);
}

public void sharedConstructing(Context context) {
        super.setClickable(true);
        this.context = context;

        paint_bmp = new Paint();
        paint_line = new Paint();

        paint_line.setAntiAlias(true);
        paint_line.setStrokeWidth(width);
        paint_line.setColor(color);
        paint_line.setStyle(Paint.Style.STROKE);
        paint_line.setStrokeJoin(Paint.Join.ROUND);
        paint_line.setStrokeCap(Paint.Cap.ROUND);
        paint_line.setAlpha(alpha);

        drawListener = new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (getDrawable() != null) {
                    int action = event.getAction();
                    switch (action) {
                        case MotionEvent.ACTION_DOWN:
                            downx = getPointerCoords(event)[0];// event.getX();
                            downy = getPointerCoords(event)[1];// event.getY();
                            break;
                        case MotionEvent.ACTION_MOVE:
                            upx = getPointerCoords(event)[0];// event.getX();
                            upy = getPointerCoords(event)[1];// event.getY();
                            canvas.drawLine(downx, downy, upx, upy, paint_line);
                            mPath = new Path();
                            paths.add(mPath);
                            invalidate();
                            downx = upx;
                            downy = upy;
                            break;
                        case MotionEvent.ACTION_UP:
                            upx = getPointerCoords(event)[0];// event.getX();
                            upy = getPointerCoords(event)[1];// event.getY();
                            canvas.drawLine(downx, downy, upx, upy, paint_line);
                            mPath = new Path();
                            paths.add(mPath);
                            invalidate();
                            break;
                        case MotionEvent.ACTION_CANCEL:
                            break;
                        default:
                            break;
                    }
                }
                return true;
            }
        };

        setOnTouchListener(drawListener);
    }

//draw view start
    public void setNewImage(Bitmap alteredBitmap, Bitmap bmp) {
        canvas = new Canvas(alteredBitmap);
        matrix_draw = new Matrix();
        canvas.drawBitmap(bmp, matrix_draw, paint_bmp);
        setImageBitmap(alteredBitmap);
        mPath = new Path();
        paths.add(mPath);
    }

@Override
    protected void onDraw(Canvas canvas) {  
            for (Path p : paths){
                canvas.drawPath(p, paint_line);
            }
    }

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

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

而是删除路径,使用Path.reset()。我给你一个我用来签名的课程......

&#13;
&#13;
public class SignatureView extends View{
	signListner sListen;

	public SignatureView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		if (context instanceof signListner) {
			sListen = (signListner) context;
		}
		init(context);

	}

	public SignatureView(Context context, AttributeSet attrs) {
		super(context, attrs);
		if (context instanceof signListner) {
			sListen = (signListner) context;
		}
		init(context);
	}

	public SignatureView(Context context) {
		super(context);
		if (context instanceof signListner) {
			sListen = (signListner) context;
		}
		init(context);
	}

	Context mContext;
	private static final float STROKE_WIDTH = 5f;
	private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;
	private Paint paint = new Paint();
	private Path path = new Path();

	private float lastTouchX;
	private float lastTouchY;
	private final RectF dirtyRect = new RectF();
	LinearLayout mContent;
	public static String tempDir;
	public int count = 1;
	public String current = null;
	private Bitmap mBitmap;
	View mView;

	private void init(Context context) {
		mContext = context;
		// LayoutInflater factory = LayoutInflater.from(context);
		/*
		 * View myView = factory.inflate(R.layout.signature_view, null);
		 * mContent = (LinearLayout) myView.findViewById(R.id.linearLayout);
		 */
		paint.setAntiAlias(true);
		paint.setColor(Color.BLACK);
		paint.setStyle(Paint.Style.STROKE);
		paint.setStrokeJoin(Paint.Join.ROUND);
		paint.setStrokeWidth(STROKE_WIDTH);
	}

	public void save() {
		Log.v("log_tag", "Width: " + this.getWidth());
		Log.v("log_tag", "Height: " + this.getHeight());
		if (mBitmap == null) {
			mBitmap = Bitmap.createBitmap(this.getWidth(), this.getHeight(),
					Bitmap.Config.ARGB_8888);
		}
		Canvas canvas = new Canvas(mBitmap);
		try {
			String root = Environment.getExternalStorageDirectory().toString();
			File myDir = new File(root + "/GetImages");
			myDir.mkdirs();
			String fname = "Image-1001.jpg";
			File file = new File(myDir, fname);
			if (file.exists())
				file.delete();

			FileOutputStream mFileOutStream = new FileOutputStream(file);

			this.draw(canvas);
			mBitmap.compress(Bitmap.CompressFormat.PNG, 90, mFileOutStream);
			// mFileOutStream.flush();
			// mFileOutStream.close();
			String url = Images.Media.insertImage(
					mContext.getContentResolver(), mBitmap, "title", null);
			Log.v("log_tag", "url: " + url);

		} catch (Exception e) {
			Log.v("log_tag", e.toString());
		}
	}

	public void clear() {
		path.reset();
		invalidate();
	}

	@Override
	protected void onDraw(Canvas canvas) {
		canvas.drawPath(path, paint);
	}

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

		switch (event.getActionMasked()) {
		case MotionEvent.ACTION_DOWN:
			sListen.onSign(true);
			path.moveTo(eventX, eventY);
			lastTouchX = eventX;
			lastTouchY = eventY;
			return true;

		case MotionEvent.ACTION_MOVE:
			resetDirtyRect(eventX, eventY);
			int historySize = event.getHistorySize();
			for (int i = 0; i < historySize; i++) {
				float historicalX = event.getHistoricalX(i);
				float historicalY = event.getHistoricalY(i);
				expandDirtyRect(historicalX, historicalY);
				path.lineTo(historicalX, historicalY);
			}
			path.lineTo(eventX, eventY);
			break;

		case MotionEvent.ACTION_UP:
			sListen.onSign(false);
			resetDirtyRect(eventX, eventY);
			int historySize1 = event.getHistorySize();
			for (int i = 0; i < historySize1; i++) {
				float historicalX = event.getHistoricalX(i);
				float historicalY = event.getHistoricalY(i);
				expandDirtyRect(historicalX, historicalY);
				path.lineTo(historicalX, historicalY);
			}
			path.lineTo(eventX, eventY);
			break;
		/*case MotionEvent.ACTION_POINTER_UP:
			sListen.onSign(false);
			break;*/
		default:
			debug("Ignored touch event: " + event.toString());
			return false;
		}

		invalidate((int) (dirtyRect.left - HALF_STROKE_WIDTH),
				(int) (dirtyRect.top - HALF_STROKE_WIDTH),
				(int) (dirtyRect.right + HALF_STROKE_WIDTH),
				(int) (dirtyRect.bottom + HALF_STROKE_WIDTH));

		lastTouchX = eventX;
		lastTouchY = eventY;

		return true;
	}

	private void debug(String string) {
	}

	private void expandDirtyRect(float historicalX, float historicalY) {
		if (historicalX < dirtyRect.left) {
			dirtyRect.left = historicalX;
		} else if (historicalX > dirtyRect.right) {
			dirtyRect.right = historicalX;
		}

		if (historicalY < dirtyRect.top) {
			dirtyRect.top = historicalY;
		} else if (historicalY > dirtyRect.bottom) {
			dirtyRect.bottom = historicalY;
		}
	}

	private void resetDirtyRect(float eventX, float eventY) {
		dirtyRect.left = Math.min(lastTouchX, eventX);
		dirtyRect.right = Math.max(lastTouchX, eventX);
		dirtyRect.top = Math.min(lastTouchY, eventY);
		dirtyRect.bottom = Math.max(lastTouchY, eventY);
	}
	
	public boolean isEmpty(){
		return path.isEmpty();
	}
}
&#13;
&#13;
&#13;

这里clear()正在清除画布。