que holder android android-canvas surfaceview

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



surfaceview android que es (13)

Para hacer un juego simple, utilicé una plantilla que dibuja un lienzo 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 lienzo se define en "ejecutar ()" / SurfaceView vive en un GameThread).

Mi primera pregunta es ¿cómo borro (o vuelvo a dibujar) todo el lienzo 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 lienzo ENTERO para un nuevo diseño (= intento 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() .


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 mapa de bits cada segundo en el SurfaceView, sin borrar la pantalla anterior. Si lo prueba, verá que el mapa de bits 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)


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, rectángulos, etc., manteniendo el mapa de bits 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.


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


Solo llama

canvas.drawColor (Color.TRANSPARENT)


Su primer requisito, cómo borrar o volver a dibujar todo el lienzo - 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.


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

codificación xml

<com.welcome.panelview.PanelViewWelcomeScreen android:id="@+id/one" android:layout_width="600px" android:layout_height="312px" android:layout_gravity="center" android:layout_marginTop="10px" android:background="@drawable/welcome" />

prueba el código anterior ...


usa el método de reinicio de la clase Path

Path.reset();


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


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