Android, canvas: ¿Cómo elimino (elimino el contenido de) un canvas (= mapas de bits), viviendo en un SurfaceView?

Para hacer un juego simple, utilicé una plantilla que dibuja un canvas con mapas de bits como este:

private void doDraw(Canvas canvas) { for (int i=0;i<8;i++) for (int j=0;j<9;j++) for (int k=0;k<7;k++) { canvas.drawBitmap(mBits[allBits[i][j][k]], i*50 -k*7, j*50 -k*7, null); } } 

(El canvas se define en “ejecutar ()” / SurfaceView vive en un GameThread).

Mi primera pregunta es ¿cómo borro (o vuelvo a dibujar) todo el canvas para un nuevo diseño?
En segundo lugar, ¿cómo puedo actualizar solo una parte de la pantalla?

 // This is the routine that calls "doDraw": public void run() { while (mRun) { Canvas c = null; try { c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { if (mMode == STATE_RUNNING) updateGame(); doDraw(c); } } finally { if (c != null) { mSurfaceHolder.unlockCanvasAndPost(c); } } } } 

¿Cómo borro (o vuelvo a dibujar) el canvas ENTERO para un nuevo diseño (= bash en el juego)?

Simplemente llame a Canvas.drawColor(Color.BLACK) o al color con el que desee borrar el Canvas .

Y: ¿cómo puedo actualizar solo una parte de la pantalla?

No hay tal método que simplemente actualice una “parte de la pantalla” ya que el sistema operativo Android está redibujando cada píxel al actualizar la pantalla. Pero, cuando no está borrando dibujos antiguos en su Canvas , los dibujos antiguos todavía están en la superficie y esa es probablemente una forma de “actualizar solo una parte” de la pantalla.

Por lo tanto, si desea “actualizar una parte de la pantalla”, simplemente evite llamar Canvas.drawColor() método Canvas.drawColor() .

Dibuja un color transparente con el modo claro de PorterDuff, lo cual es el truco para lo que yo quería.

 Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR) 

Encontré esto en grupos de google y esto funcionó para mí …

 Paint clearPaint = new Paint(); clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); canvas.drawRect(0, 0, width, height, clearPaint); 

Esto elimina dibujos, rectangularjs, etc., manteniendo el bitmap establecido.

Intenté la respuesta de @mobistry:

canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);

Pero no funcionó para mí.

La solución, para mí, fue:

canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);

Quizás alguien tenga el mismo problema.

 mBitmap.eraseColor(Color.TRANSPARENT); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 

usa el método de reinicio de la clase Path

 Path.reset(); 

por favor pegue el código debajo en surfaceview extienda el constructor de la clase ………….

código de constructor

  SurfaceHolder holder = getHolder(); holder.addCallback(this); SurfaceView sur = (SurfaceView)findViewById(R.id.surfaceview); sur.setZOrderOnTop(true); // necessary holder = sur.getHolder(); holder.setFormat(PixelFormat.TRANSPARENT); 

encoding xml

   

prueba el código anterior …

Para mí, llamar a Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR) o algo similar solo funcionaría después de tocar la pantalla. Así que llamaría a la línea de código anterior, pero la pantalla solo se borrará después de tocar la pantalla. Entonces, lo que funcionó para mí fue llamar a invalidate() seguido de init() que se llama en el momento de la creación para inicializar la vista.

 private void init() { setFocusable(true); setFocusableInTouchMode(true); setOnTouchListener(this); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setDither(true); mPaint.setColor(Color.BLACK); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(6); mCanvas = new Canvas(); mPaths = new LinkedList<>(); addNewPath(); } 

Aquí está el código de un ejemplo mínimo que muestra que siempre debe volver a dibujar cada píxel del Lienzo en cada cuadro.

Esta actividad dibuja un nuevo bitmap cada segundo en el SurfaceView, sin borrar la pantalla anterior. Si lo prueba, verá que el bitmap no siempre se escribe en el mismo búfer, y la pantalla alternará entre los dos búferes.

Lo probé en mi teléfono (Nexus S, Android 2.3.3) y en el emulador (Android 2.2).

 public class TestCanvas extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new TestView(this)); } } class TestView extends SurfaceView implements SurfaceHolder.Callback { private TestThread mThread; private int mWidth; private int mHeight; private Bitmap mBitmap; private SurfaceHolder mSurfaceHolder; public TestView(Context context) { super(context); mThread = new TestThread(); mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon); mSurfaceHolder = getHolder(); mSurfaceHolder.addCallback(this); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mWidth = width; mHeight = height; mThread.start(); } @Override public void surfaceCreated(SurfaceHolder holder) {/* Do nothing */} @Override public void surfaceDestroyed(SurfaceHolder holder) { if (mThread != null && mThread.isAlive()) mThread.interrupt(); } class TestThread extends Thread { @Override public void run() { while (!isInterrupted()) { Canvas c = null; try { c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { c.drawBitmap(mBitmap, (int) (Math.random() * mWidth), (int) (Math.random() * mHeight), null); } } finally { if (c != null) mSurfaceHolder.unlockCanvasAndPost(c); } try { sleep(1000); } catch (InterruptedException e) { interrupt(); } } } } } 

Canvas.drawColor (Color.TRANSPARENT, PorterDuff.Mode.CLEAR)

 canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY); 

Tuve que usar un pase de dibujo por separado para limpiar el canvas (bloquear, dibujar y desbloquear):

 Canvas canvas = null; try { canvas = holder.lockCanvas(); if (canvas == null) { // exit drawing thread break; } canvas.drawColor(colorToClearFromCanvas, PorterDuff.Mode.CLEAR); } finally { if (canvas != null) { holder.unlockCanvasAndPost(canvas); } } 

Su primer requisito, cómo borrar o volver a dibujar todo el canvas – Respuesta – utilice el método canvas.drawColor (color.Black) para borrar la pantalla con un color negro o lo que especifique.

Su segundo requisito, cómo actualizar parte de la pantalla – Respuesta – por ejemplo, si desea mantener todas las otras cosas sin cambios en la pantalla, pero en un área pequeña de la pantalla para mostrar un entero (decir contador) que aumenta después de cada cinco segundos. luego use el método canvas.drawrect para dibujar esa pequeña área especificando la parte superior superior izquierda inferior y pintar. luego calcule el valor de su contador (usando postdalayed por 5 segundos, etc., llike Handler.postDelayed (Runnable_Object, 5000);), conviértalo en cadena de texto, calcule la coordenada xey en este pequeño rect y use la vista de texto para mostrar el cambio valor del contador.

Solo llama

canvas.drawColor (Color.TRANSPARENT)