2016-03-01 44 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

相关问题