我试图在Android的Api演示中的Fingerpaint应用程序上实现擦除功能。我根据自己的需要更改了一些代码。起初擦除功能很好。我用过:
drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
在位图中绘制路径时效果很好。但是当我实现Undo和Redo功能时(我实现它的方式是使用两个arraylist并保存路径),PorterDuffXfermode不起作用。请看一下:
在图像1中,我绘制了一些路径(存储在arraylist中。未在位图画布中绘制) 然后在2,那时我按下了擦除图标。我不知道是什么导致所有路径变黑。然后在3我试图擦除我做的路径(PorterDuffXFermode有人说它是黑色的)。然后当我切换回绘图模式。似乎相反或删除,它所做的只是绘制另一条道路。
任何解决方案?或解决方法? 这是我的drawingClass的代码:
//this is where the drawing takes place
public class DrawingClass extends View{
//drawing path
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF660000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
private float brushSize,lastBrushSize;
private boolean erase = false;
//array list for paths
private ArrayList<PathPoints> paths = new ArrayList<PathPoints>();
private ArrayList<PathPoints> undonePaths = new ArrayList<PathPoints>();
public Context context;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
public DrawingClass(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
this.context = context;
setupDrawing();
}
private void setupDrawing(){
setFocusable(true);
setFocusableInTouchMode(true);
//instantiate the variable to get the last brush size
brushSize = getResources().getInteger(R.integer.medium_size);
lastBrushSize = brushSize;
//get drawing area setup for interaction
drawCanvas = new Canvas();
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
//initial properties
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(brushSize);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
//paths.add(new PathPoints(drawPath, paintColor, brushSize));
}
public void setBrushSize(float newSize){
//update brush size
float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
newSize, getResources().getDisplayMetrics());
brushSize = pixelAmount;
drawPaint.setStrokeWidth(brushSize);
invalidate();
}
public void setLastBrushSize(float lastSize){
//set the last brush size
lastBrushSize = lastSize;
invalidate();
}
public float getLastBrushSize(){
//return the last brush size
return lastBrushSize;
}
public void setErase(boolean isErase){
//set erase true or false
erase = isErase;
if (erase) {
//drawPaint.setColor(Color.WHITE);
drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
else drawPaint.setXfermode(null);
}
public void startNew(){
//creates a new canvass
drawCanvas.drawColor(0,PorterDuff.Mode.CLEAR);
drawCanvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
setDrawingCacheEnabled(true);
String imgSaved = MediaStore.Images.Media.insertImage(
context.getContentResolver(), getDrawingCache(),
UUID.randomUUID().toString()+".png", "drawing");
destroyDrawingCache();
paths.clear();
undonePaths.clear();
invalidate();
}
@Override
protected void onSizeChanged(int w,int h,int oldw,int oldh){
//view given size
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
@Override
protected void onDraw(Canvas canvas){
//draw view
//save the strokes in the bitmap
//canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
for (PathPoints p : paths){
drawPaint.setColor(p.getColor());
drawPaint.setStrokeWidth(p.getBrush());
invalidate();
canvas.drawPath(p.getPath(), drawPaint);
}
}
private void touch_start(float x, float y){
drawPath.reset();
drawPath.moveTo(x, (float) (y+.1));
drawPath.lineTo(x, y);
drawPath.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) {
drawPath.quadTo(mX, mY, (x + mX)/2, (y+ mY)/2);
mX = x;
mY = y;
}
}
private void touch_up(){
drawPath.lineTo(mX, mY);
drawCanvas.drawPath(drawPath, drawPaint);
drawPath = new Path();
paths.add(new PathPoints(drawPath, paintColor, brushSize));
}
@Override
public boolean onTouchEvent(MotionEvent event){
//detect user touch
float touchX = event.getX();
float touchY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
invalidate();
touch_start(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
invalidate();
touch_move(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
invalidate();
touch_up();
drawPath.reset();
break;
default:
return false;
}
invalidate();
return true;
}
public void undoPath(){
if (paths.size()>0) {
undonePaths.add(paths.remove(paths.size()-1));
} else {
Log.d("Undo", "No paths left");
}
invalidate();
}
public void redoPath(){
if (undonePaths.size()>0) {
paths.add(undonePaths.remove(undonePaths.size()-1));
} else {
Log.d("Redo", "No paths left");
}
invalidate();
}
public void setColor(String newColor){
//set color
paintColor = Color.parseColor(newColor);
drawPaint.setColor(paintColor);
invalidate();
}
class PathPoints{
private Path path;
private int color;
private float brushsize;
private int x, y;
//holds the paths data
public PathPoints(Path path, int color, float brushsize) {
this.path = path;
this.color = color;
this.brushsize = brushsize;
}
public Path getPath() {
return path;
}
public void setPath(Path path) {
this.path = path;
}
public float getBrush(){
return brushsize;
}
public void setBrush(float brushsize){
this.brushsize = brushsize;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
}