2013-02-21 43 views
3

我可以讓它畫出路徑,我移動手指時用透明線刪除,還是不畫?帶PorterDuff.Mode.CLEAR的橡皮擦總是畫一條黑線,我想要刪除的地方

我這是怎麼實例化我的橡皮:

OnClickListener eraseListener = new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      mPaint.setColor(0x00000000); 
      mPaint.setXfermode(clear); 
      mPaint.setAlpha(0x00); 
      myView.setPaint(mPaint); 
      LogService.log("PaintActivity", "------in eraseListener"); 

     } 
    }; 

這臺從我的觀點,即包含畫布上的油漆。 在這裏,我有以下動作事件:

private void touch_start(float x, float y) { 
    mPath.reset(); 
    mPath.moveTo(x, y); 
    mX = x; 
    mY = y; 
} 
private void touch_move(float x, float y) { 
    float dx, dy; 
     dx = Math.abs(x - mX); 
     dy = Math.abs(y - mY); 
    if ((dx >= TOUCH_TOLERANCE) || (dy >= TOUCH_TOLERANCE)) { 
     undoPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); 
     mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); 
      mX = x; 
      mY = y; 
    } 
} 
private void touch_up() { 
    mPath.lineTo(mX, mY); 
    mPath.moveTo(mX, mY); 
    canvas.drawPath(mPath, paint); 
    mPath.reset(); 
} 
public boolean onTouchEvent(MotionEvent event) { 
    float x = event.getX(); 
    float y = event.getY(); 
    switch (event.getAction()) { 
    case MotionEvent.ACTION_DOWN: 
     touch_start(x, y); 
     break; 
    case MotionEvent.ACTION_MOVE: 
     touch_move(x, y); 
     invalidate(); 
     break; 
    case MotionEvent.ACTION_UP: 
     touch_up(); 
     invalidate(); 
     break; 
    } 
    return true; 
} 

現在,如果我要刪除,正如我所說的,當我移動我的手指,它繪製路徑上的黑線。當我在touch_up上取下手指時,會清除它所畫黑線背面的內容。如果我評論invalidate();從touch_move函數開始,那麼它將不會繪製黑線,而且它只會在touch_up上擦除。我不能實時擦除它嗎?

+0

Offtopic:我看到你回答了很多你自己的問題,這可能表明你在提問之前沒有付出很多的努力**。請考慮一下。與你的問題相關,你不能簡單地在兩個連續的移動接觸點之間做一個小路徑,並畫出/清除那個小路徑(類似於你在移動和觸摸事件之間做的),在每次移動之後重置路徑? – Luksprog 2013-02-21 10:25:38

+0

不,因爲我需要從我觸摸屏幕的那一刻開始連續的路徑(touch_down),直到我按下屏幕(touch_up)的那一刻。因爲我需要保存整個路徑,以防我想調用撤消功能。此外,使用的路徑與繪製,刪除和移動圖片/形狀相同 – 2013-02-21 10:46:34

+0

您可以有一個額外的路徑來存儲用戶所做的整個移動(您目前使用的)和臨時小路徑如上所述。 – Luksprog 2013-02-21 10:52:19

回答

10

我解決這樣的:

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); 

     mPath.lineTo(mX, mY); 
     // commit the path to our offscreen 
     mCanvas.drawPath(mPath, mPaint); 
     mPath.reset(); 
     mPath.moveTo(mX, mY); 

     mX = x; 
     mY = y; 
    } 
} 

在這裏,我添加了一行到路徑,提請路徑,重置路徑,並在touch_move方法使用moveTo

touch_up我只使用mPath.reset()

private void touch_up() { 

    // kill this so we don't double draw 
    mPath.reset(); 

} 

這使我的橡皮擦透明 - 擦除時沒有黑線。

+0

它可以完美的,但如何實現使用此功能撤消功能? – 2013-11-09 18:03:11

+0

優秀的答案... – Santosh 2013-11-20 13:30:14

+0

使用這個答案的缺點,它創建一個模糊線。 – 2015-04-04 09:55:32

4

要刪除無黑線修改中的onDraw)代碼(:

@Override 
protected void onDraw(Canvas canvas) { 
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 
    if (mMode != PAINT_MODE) { 
     return; 
    } 
    canvas.drawPath(mPath, mPaint); 
} 

,如果你想使手指擦除更自然,修改TOUCH_MOVE的代碼()

if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { 
    mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); 
    mX = x; 
    mY = y; 
    if (mMode != PAINT_MODE) { 
     mCanvas.drawPath(mPath, mPaint); 
    } 
+0

什麼是PAINT_MODE和mMode? – RPallas 2014-07-18 06:51:16

+0

您自己的值指示您當前正在使用哪種繪圖模式。例如PAINT_MODE = 0; ERASE_MODE = 1; – vals 2014-07-21 18:00:39

7

只需打開HWA關閉。

,或者你可以在構造函數中

setLayerType(View.LAYER_TYPE_SOFTWARE, mPaint); 
0

添加此行畫布繪製你的原始位之前就繪製相同大小的一個更加透明位圖。

Bitmap b = Bitmap.createBitmap(orgBM.getWidth(), orgBM.getHeight(), Bitmap.Config.ARGB_8888); 

Canvas c = new Canvas(); 
c.setBitmap(b); 

c.drawBitmap(orgBM, 0, 0, null);