2012-01-26 6 views
5

Creé una Vista personalizada extendiendo desde la Vista. En onDraw() logré dibujar algunos círculos y otras cosas. Pero ahora quiero agregar un fondo de un recurso (tarjeta SD o una secuencia) que en realidad es un mapa que descargo de nuestro servidor y que dibujo sobre él. Es para Android 8+Fondo del dibujo de la vista personalizada desde el archivo .png en Android

@Override 
protected void onDraw(Canvas canvas) { 
    Canvas g = canvas; 
    String file = "/mnt/sdcard/download/tux.png"; 
    Bitmap bg = null; 
    try { 
     bg = BitmapFactory.decodeFile(file); 
     g.setBitmap(bg); 
    } catch (Exception e) { 
     Log.d("MyGraphics", "setBitmap() failed according to debug"); 
    } 
} 

De alguna manera g.setBitmap (BG) sigue fallando, no he visto las especificaciones técnicas de imagen, pero en realidad es sólo una imagen de Tux (hay 24 bits de colores) de formato PNG. ¿Puede alguien darme algunos consejos sobre cómo agregar una imagen de fondo para poder dibujar sobre ella? Gracias.

Respuesta

9

En realidad, no desea dibujar en el mapa de bits que carga, solo desea dibujarlo en el lienzo, por lo que debe utilizar Canvas.drawBitmap(). Tampoco debería cargar un mapa de bits en cada onDraw(), sino en el constructor. Trate de esta clase:

package com.example.android; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.util.AttributeSet; 
import android.view.View; 

public class CustomView extends View { 
    private final Bitmap mBitmapFromSdcard; 

    public CustomView(Context context) { 
     this(context, null); 
    } 

    public CustomView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     mBitmapFromSdcard = BitmapFactory.decodeFile("/mnt/sdcard/download/tux.png"); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     Canvas g = canvas; 
     if (mBitmapFromSdcard != null) { 
      g.drawBitmap(mBitmapFromSdcard, 0, 0, null); 
     } 
    } 
} 

También puede dejar que Android dibujar el mapa de bits en el fondo:

package com.example.android; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.drawable.BitmapDrawable; 
import android.util.AttributeSet; 
import android.view.View; 

public class CustomView extends View { 
    public CustomView(Context context) { 
     this(context, null); 
    } 

    public CustomView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     Bitmap bm = BitmapFactory.decodeFile("/mnt/sdcard/download/tux.png"); 
     if (bm != null) { 
      setBackgroundDrawable(new BitmapDrawable(bm)); 
     } 
    } 
} 
+0

Martin, Muchas gracias por este claro ejemplo. ¡Qué extraño que ya hice tu primer ejemplo y de alguna manera no funcionó! Ahí es donde comencé a perderme. El segundo se está estirando para encajar en el aspecto inmobiliario de la vista, eso es exactamente lo que finalmente tuvo. Pero a su primero me gusta mucho, así puedo posicionar la imagen sin modificar su tamaño. – AndaluZ

+0

Cuando prueba mi primer ejemplo, ¿qué es exactamente lo que no funciona? Una excepción (en caso afirmativo, ¿qué excepción)? Nada se dibuja en la pantalla? ¿En qué versión de Android estás corriendo? ¿Puede proporcionar el código exacto que usa que espera que funcione, pero no es así? –

+0

Funciona mi amigo, con .png y .jpg. Después de su publicación todavía estaba jugando y probando algunas imágenes y descubrí que no todos los archivos .jpeg funcionan. Cuando uso imágenes pequeñas de jpg como 50 KB, funciona, pero cuando utilizo imágenes jpg más grandes, como 600 KB, el fondo se vuelve completamente blanco. No sé si tiene que ver con el tamaño de la imagen, porque aquellos que no funcionan tienen un tamaño mucho más grande que el de mi vista. El uso de setBackgroundDrawable() funciona, pero también se reduce al tamaño de la propiedad de la Vista. – AndaluZ

0

Me temo que obtienes OutOfMemoryError, porque se llama a onDraw muchas veces durante el ciclo de vida de la vista, y cada vez que estás asignando memoria para un nuevo mapa de bits. Simplemente haga miembro bg (tal vez - estático) de su clase y cárguelo solo una vez - en el constructor de su vista. Y no se olvide de reciclar mapa de bits en la separación de la vista.

+0

Bueno, esto sucede en la primera vez, he puesto un punto de interrupción en: bg = BitmapFactory. decodificar (archivo); Durante la depuración, la excepción se produce en g.setBitmap (bg); Obtengo una IllegalStateException, pero no pude recuperar más información sobre esta excepción. Me temo que tiene que ver con el tamaño o la densidad del mapa de bits, pero mi conocimiento es limitado cuando se trata de gráficos. – AndaluZ

+0

Ok, descubrí que bg = BitmapFactory.decodeFile (archivo); devuelve un mapa de bits inmutables, lo que significa que no puedo recurrir a él. ¿Puede alguien proporcionarme simplemente un ejemplo simple de cómo cargar una imagen desde un archivo (o un bytearray) y ponerla como una imagen de fondo de una vista personalizada, para que pueda dibujar sobre ella en el controlador onDraw() de la vista? Solo un simple ejemplo, gracias. – AndaluZ

+0

Puedo proponer dos formas de hacer esto: 1) llamar internamente a View.setBackgroundDrawable() (previamente necesita crear BitmapDrawable desde mapa de bits); 2) llame a g.drawBitmap() en lugar de g.setBitmap(). En este caso, no reemplaza la fuente de lienzo, sino que dibuja en ella. – OleGG

Cuestiones relacionadas