2016-03-01 69 views
0

我有一個自定義surfaceView,它將根據Touch事件繪製表面。當我在這個視圖上畫東西時,它工作正常。但是當我試圖擦除油漆時,沒有任何東西被抹去。請找到下面的示例代碼片段:清除功能在自定義SurfaceView Android中不起作用

public class MySurfaceView extends SurfaceView { 
private static final String TAG = "FreeHandDrawing"; 
public static Canvas mCanvas; 
SurfaceHolder holder; 
private static Path path; 
private Paint paint; 
private ArrayList<Path> pathArrayList = new ArrayList<>(); 
private boolean freeHandMode; 

public MySurfaceView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    freeHandMode = false; 
    path = new Path(); 
    holder = getHolder(); 
    holder.setFormat(PixelFormat.TRANSPARENT); 
    setDrawingCacheEnabled(true); 

    this.setZOrderOnTop(true); 

    paint = new Paint(); 
    paint.setAntiAlias(true); 
    paint.setColor(0xFF22FF11); 
    paint.setStyle(Paint.Style.STROKE); 
    paint.setStrokeJoin(Paint.Join.ROUND); 
    paint.setStrokeCap(Paint.Cap.ROUND); 
    paint.setStrokeWidth(8); 

} 


@Override 
public boolean onTouchEvent(MotionEvent event) { 

    if(freeHandMode) { 

     if (event.getAction() == MotionEvent.ACTION_DOWN) { 

      Log.d("Action", "Placed"); 
      path.moveTo(event.getX(), event.getY()); 

     } else if (event.getAction() == MotionEvent.ACTION_MOVE) { 

      Log.d("Action", "Moved"); 
      path.lineTo(event.getX(), event.getY()); 
      pathArrayList.add(path); 

     } 

     mCanvas = holder.lockCanvas(); 
     if (mCanvas != null) { 
      if (pathArrayList.size() > 0) { 

       mCanvas.drawPath(pathArrayList.get(pathArrayList.size() - 1), paint); 

      } 
      holder.unlockCanvasAndPost(mCanvas); 

     } else { 
      Log.d(TAG, "Canvas is NULL"); 
     } 
    } 
    invalidate(); 
    return true; 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    Log.d(TAG, "On draw called"); 

} 

public void eraseDrawing() { 
    pathArrayList.clear(); 
    invalidate(); 
} 

public void drawEnableDisable(boolean mode) { 
    freeHandMode = mode; 
    } 
}             

上面的代碼有什麼問題?

回答

0

你應該讓你的繪製代碼在onDraw方法

@Override 
protected void onDraw(Canvas canvas) { 
    // In case you want to delete/erase when path array/list is cleared. 
    if (pathArrayList.size() == 0) { 
     canvas.drawColor(0, Mode.CLEAR); 
    } 
    // In case, you want to draw all paths also in onDraw 
    for(Path path : pathArrayList) { 
     canvas.drawPath(path, paint); 
    } 
} 

如果清除路徑列(列表),然後在調用無效()的onDraw被觸發。

注意:您應該在onTouchEvent()的末尾調用invalidate()來通知系統更新屏幕。調用invalidate()會讓框架最終調用onDraw()。

你也不應該使用canvas通過lockCanvas得到它不會被硬件加速。相反,您應該使用作爲參數傳遞給onDraw()本身的畫布。

您可以選擇讓系統變得有點智能,無需在每一幀中繪製路徑的拉列表,而是通過使用特殊標誌來處理擦除/重畫等。否則,只需渲染最近一次調用onTouchEvent()所生成的最新路徑。

+0

感謝Bajaj的回覆。如果我嘗試在onTocuhEvent中繪製,它是否會影響性能?上面給出的代碼似乎對繪製或擦除沒有任何影響,它不起作用。 – vgokul129

+0

你確定你在視圖上調用invalidate()嗎? 是的,如果視圖已經失效,onDraw()會在渲染過程中由框架調用。它可能位於不同的線程(渲染線程)中,因此在onTouchEvent(從UI /主線程調用)中執行復雜的操作不是可取的。 –

+0

onDraw方法沒有被觸發,我已經檢查了onDraw中定義的日誌,但沒有這樣的日誌。我錯過了什麼嗎? – vgokul129

相關問題