2015-12-22 127 views
3

我有一個自定義視圖類,它擴展了視圖。我正在使用over-ridden onDraw方法在畫布上進行塗鴉。我有一個POJO,其中包括路徑和塗料在其幫助下,我可以重新創建舊的路徑繪製的列表,像這樣:使用畫布的橡皮擦效果

@Override 
protected void onDraw(Canvas canvas){ 
for (POJO pojo : pojoList { 
    canvas.drawPath(pojo.path, pojo.paint); 
} 
canvas.drawPath(path, paint); 
} 

我想要實現擦除功能,它應該像一個適當的抹去。我知道一種方法來寫入位圖並使用setXfermode來清除正常工作的CLEAR。但像素化在小分辨率設備上看起來不太好。我不想在這個視圖下面使用WHITE彩色顏料,因爲我有一個ImageView,因此將它着色爲白色也會影響ImageView。 任何想法或解決這個問題的代碼非常感謝。

回答

0

這工作得很好。如果有人找到更好的解決方案。請更新

private Context mContext; 
private ArrayList<Draw> mDrawList; 
private Paint mPaint; 
private Path mPath; 
private boolean isErase; 
private float mX, mY; 
private static final float TOUCH_TOLERANCE = 4; 

public EraseDoodleView(Context context) { 
    super(context); 
    init(context); 
} 

public EraseDoodleView(Context context, AttributeSet attributeSet) { 
    super(context, attributeSet); 
    init(context); 
} 

private void init(Context context) { 
    mContext = context; 
    mDrawList = new ArrayList<Draw>(); 
    mPath = new Path(); 
    setupPaint(); 
    setLayerType(View.LAYER_TYPE_HARDWARE, mPaint); 
} 

private void setupPaint() { 
    mPaint = new Paint(); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setStrokeJoin(Paint.Join.ROUND); 
    mPaint.setStrokeCap(Paint.Cap.ROUND); 
    mPaint.setFilterBitmap(true); 
    mPaint.setAntiAlias(true); 
    mPaint.setStrokeWidth(4); 
    mPaint.setColor(ContextCompat.getColor(mContext, android.R.color.black)); 
    if (isErase) { 
     mPaint.setXfermode(new PorterDuffXfermode(
       PorterDuff.Mode.CLEAR)); 
     mPaint.setStrokeWidth(16); 
    } 
} 

public void setErase(boolean isErase) { 
    this.isErase = isErase; 
    setupPaint(); 
} 

public boolean getErase() { 
    return this.isErase; 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    for (Draw draw : mDrawList) { 
     canvas.drawPath(draw.path, draw.paint); 
    } 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 

    float x = event.getX(); 
    float y = event.getY(); 

    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      touchStart(x, y); 
      invalidate(); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      touchMove(x, y); 
      invalidate(); 
      break; 
     case MotionEvent.ACTION_UP: 
      touchUp(); 
      invalidate(); 
      break; 
    } 
    return true; 
} 

private void touchStart(float x, float y) { 
    mPath.reset(); 
    mPath.moveTo(x, y); 
    mDrawList.add(new Draw(mPath, mPaint)); 
    mX = x; 
    mY = y; 
} 
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; 
    } 
} 

private void touchUp() { 
    mPath.lineTo(mX, mY); 
    mPath = new Path(); 
} 


class Draw { 
    Path path; 
    Paint paint; 

    public Draw(Path path, Paint paint) { 
     this.paint = paint; 
     this.path = path; 
    } 
}