2011-02-10 5 views
12

Estoy convirtiendo con éxito un ViewGroup (RelativeLayout) en un mapa de bits utilizando un lienzo. Sin embargo, cuando ocurre el sorteo, solo veo el ViewGroup con su fondo dibujable y no sus elementos secundarios (dos TextViews) que deben distribuirse dentro de RelativeLayout usando reglas como FILL_PARENT.Problemas con Android Convertir ViewGroup con niños en mapa de bits

El RelativeLayout se crea utilizando la siguiente función estática:

public static RelativeLayout createProgrammeView(Context context, int width, int height, String title, String time) { 
    RelativeLayout.LayoutParams params; 

    // Layout Root View (RelativeLayout) 
    RelativeLayout rlv = new RelativeLayout(context); 
    params = new RelativeLayout.LayoutParams(width, height); 
    rlv.setLayoutParams(params); 
    rlv.setPadding(3, 3, 3, 3); 
    rlv.setBackgroundResource(R.drawable.background); 

    // Layout Title 
    TextView tv = new TextView(context); 
    params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT); 
    params.addRule(RelativeLayout.ALIGN_PARENT_TOP); 
    params.addRule(RelativeLayout.ALIGN_PARENT_LEFT); 
    params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 
    tv.setId(R.id.title); 
    tv.setLayoutParams(params); 
    tv.setGravity(Gravity.CENTER_VERTICAL); 
    tv.setSingleLine(true); 
    tv.setEllipsize(TruncateAt.END); 
    tv.setTextColor(Color.parseColor("#fff")); 
    tv.setTextSize(11); 
    tv.setText(title); 
    rlv.addView(tv); 

    // Layout Start Time 
    tv = new TextView(context); 
    params = new RelativeLayout.LayoutParams(16, RelativeLayout.LayoutParams.WRAP_CONTENT); 
    params.addRule(RelativeLayout.BELOW, R.id.title); 
    params.addRule(RelativeLayout.ALIGN_PARENT_LEFT); 
    params.setMargins(0, 4, 0, 0); 
    tv.setId(R.id.time); 
    tv.setLayoutParams(params); 
    tv.setGravity(Gravity.CENTER_VERTICAL); 
    tv.setSingleLine(true); 
    tv.setEllipsize(null); 
    tv.setTextColor(Color.parseColor("#fff")); 
    tv.setTextSize(10); 
    tv.setText(time); 
    rlv.addView(tv); 
    } 

    return rlv; 
} 

entonces la siguiente manera para convertir la RelativeLayout en un mapa de bits:

public static Bitmap loadBitmapFromView(RelativeLayout v) { 
    Bitmap b = Bitmap.createBitmap(v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.RGB_565); 
    Canvas c = new Canvas(b); 
    v.draw(c); 
    return b; 
} 

Como era de esperar que esto me da un buen mapa de bits en las dimensiones que requiero con el fondo dibujable, pero los niños no están en el mapa de bits. A estas funciones las llamo bastante para construir una imagen grande que luego se dibuja en una vista personalizada en mi actividad.

Este es el bucle que llama a la función estática:

public static void renderViews(final Context context) { 
    largeBitmap = Bitmap.createBitmap(largeWidth, largeHeight, Bitmap.Config.RGB_565); 
    Canvas largeCanvas = new Canvas(largeBitmap); 

    for (int i = 0; i < items.size(); i++) { 
     int leftMargin = ...SOME CALCULATIONS...; 

     RelativeLayout newView = createProgrammeView(context, width, rowHeight, "Title", "21:00"); 
     Bitmap newViewBitmap = loadBitmapFromView(newView); 

     largeCanvas.drawBitmap(newViewBitmap, leftMargin, 0, new Paint()); 
    } 

    myCustomView.invalidate(); 
} 

Mi vista personalizada anula el onDraw función():

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    canvas.drawBitmap(largeBitmap, 0, 0, null); 
} 

Por lo que puedo ver Creo que esto se debe a que Android doesn no llame a una medida() en las vistas secundarias. He intentado llamar esto manualmente, pero esto no resuelve el problema.

Así que, supongo que lo que me gustaría saber es cómo puedo convertir un RelativeLayout con niños en un mapa de bits y hacer que Android mida a los niños para que respeten sus reglas de diseño relativas.

Muchas gracias a todos los que me pueden ayudar a resolver esto.

Rob

Respuesta

22

El problema es que que no midieron y el diseño del envase. Debe llamar al v.measure(widthSpec, heightSpec) y luego al v.layout(left, top, right, bottom) antes de que el dibujo pueda funcionar. El primer método se asegurará de que la vista sepa cuán grande quiere que sea, y el segundo método asegurará que los niños estén posicionados correctamente.

En su caso puede hacer:

v.measure(MeasureSpec.makeMeasureSpec(v.getLayoutParams().width, MeasureSpec.EXACTLY), 
     MeasureSpec.makeMeasureSpec(v.getLayoutParams().height, MeasureSpec.EXACTLY)); 
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); 

Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.RGB_565); 
Canvas c = new Canvas(b); 
v.draw(c); 
+0

Excelente. ¡Muchas gracias, Romain! Sabía que tenía algo que ver con measure() y layout(), pero no entendía cómo atarlo todo. Gracias de nuevo. –

+0

funcionó para mí también. ¡Gracias! – Doigen

+0

Funcionó para mí también. Gracias .. –

0

solución que en base a DisplayMetrics para los diseños podrían ser útiles también. Para no repetir - look here.

Cuestiones relacionadas