2011-01-10 15 views
11

Estoy intentando cambiar la imagen de fondo de una vista personalizada con cierto éxito. la imagen cambiará pero el problema es que todavía veo rastros de la imagen anterior. cuando intento limpiar el lienzo antes de dibujar la imagen nueva, parece que no funciona. Yo creo un mapa de bits para almacenar la imagen. cuando cambio la imagen, llamo a Canvas.drawColor() antes de dibujar la nueva imagen, pero la imagen anterior persiste. He intentado drawColor (0), drawColor (Color.BLACK), c.drawColor (0, PorterDuff.Mode.CLEAR), y ninguno de los anteriores funciona. como tal, tuve que publicar esto para su revisión por parte de mentes más experimentadas que la mía.Borrado de lienzo con Canvas.drawColor()

el código actual es la siguiente:

private int bgnd; 
private boolean switching; 

public void setBgnd(int incoming){ 
    switching = true; 
    switch (incoming){ 

    case R.drawable.image1: 
     bgnd = incoming; 
     this.invalidate(); 
     break; 

    case R.drawable.image2: 
     bgnd = incoming; 
     this.invalidate(); 
     break; 

    } 
} 



protected void onDraw(Canvas c){ 
    if(switching == true){ 
     Bitmap b = BitmapFactory.decodeResource(getResources(), bgnd); 
     c.drawColor(0, PorterDuff.Mode.CLEAR); 
     c.drawBitmap(b, 0, 0, null); 
     switching = false; 

    }else{ 
     Bitmap b = BitmapFactory.decodeResource(getResources(), bgnd); 
     c.drawBitmap(b, 0, 0, null); 
    } 
} 

Respuesta

30

Al igual que usted, luché para limpiar una capa superior/vista de superficie en mi aplicación de capas múltiples/vista de superficies. Después de 2 días buscando y codificando, descubrí mi propio camino y así es como limpié un lienzo antes de dibujar, puedes usarlo cuando tienes varias capas/vistas superficiales. La capa de fondo no estará cubierta de negro, ese es el truco.

Paint paint = new Paint(); 
paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR)); 
canvas.drawPaint(paint); 
paint.setXfermode(new PorterDuffXfermode(Mode.SRC)); 
// start your own drawing 
+0

Creo que me hubiera llevado más de 2 días resolver esto frente a los 2 minutos que tardé en llegar aquí. Thx strangeInAStrangerLand + longdooooo –

2

¿No necesita también invalidarse la llamada() desde dentro de su método onDraw, por lo que los cambios realizados en ese onDraw se actualizan en la pantalla?

La invalidate() en su interruptor invocará su onDraw después de llamar a setBgnd, pero no hay nada que diga volver a dibujar después de haber realizado cambios en el lienzo.

+1

tengo la impresión de que llamar a invalidate() le indicará a una vista que llame a onDraw() y dibuje su auto. siendo el caso, poner esa llamada en el método provocaría que se repitiera para siempre, como se ve en el ejemplo en: http://www.anddev.org/basic_and_simple_2d_drawing_-_animation-t3085.html – Prmths

+0

Ah tienes razón, tenías que búsquelo, http://developer.android.com/guide/topics/graphics/index.html. Lo siento, mi entendimiento no era correcto. – C0deAttack

+0

Pensé que al principio, también. La pregunta para mí es: si invalidate() le dice a una vista que se rediseñe a sí misma, ¿por qué esta vista no se vuelve a dibujar por completo hasta que se mueve más adelante en una animación? la mitad inferior del objeto se ve bien, pero la otra mitad sigue siendo la superficie anterior. – Prmths

2

Puede utilizar el método de Canvas drawRGB.

+0

drawRGB() no borra el canal alfa y el mapa de bits se volverá opaco, por lo tanto, solo se puede usar si el mapa de bits es la única capa o la capa de fondo. También hay un método drawARGB(), que también permite tratar el canal alfa. Aunque no lo he probado si funciona. –

+1

Tenga en cuenta que drawRGB solo usa 'drawColor (Color.rgb (r, g, b))' – TameHog