2012-09-11 18 views
7

Este es mi código con FrameLayout:FrameLayout, vistas niño no se muestran más

<FrameLayout 
     android:layout_width="fill_parent" android:layout_height="wrap_content"> 
    <ImageView 
      android:id="@+id/frameView" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:src="@drawable/image1" 
      /> 
</FrameLayout> 

El espectáculo ImageView también.

Ahora tengo un diseño personalizado que se extiende desde FrameLayout, p. MyFrameLayout.

En MyFrameLayout, quiero que la altura de la disposición es siempre la mitad de la anchura, por lo que mi código es:

public class MyFrameLayout extends FrameLayout { 

    // 3 constructors just call super 

    @Override 
    protected void onMeasure(int widthMeasureSpec, 
         int heightMeasureSpec) { 
     int width = MeasureSpec.getSize(widthMeasureSpec); 
     int height = (int) (width * 0.5); 
     setMeasuredDimension(width, height); 
    } 
} 

luego usarlo en xml:

<com.test.MyFrameLayout 
     android:layout_width="fill_parent" android:layout_height="wrap_content"> 
    <ImageView 
      android:id="@+id/frameView" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:src="@drawable/image1" 
      /> 
</com.test.MyFrameLayout> 

Pero ahora el interior ImageView desapareció.

Creo que no implemento onMeasure o onLayout correctamente. Creo que también necesito cambiar el tamaño de las vistas de los niños. Pero no sé qué hacer ahora.


ACTUALIZACIÓN

por comentario TheDimasig 's, acabo de revisar mi código y actualizar mi pregunta. Gracias

+0

Dos sugerencias: 1. Compruebe sus métodos 'onMeasure' y' onLayout' en su clase 'MyFrameLayout'. 2. Intente utilizar la herramienta hierarhyviewer para la depuración. Además, si es posible mostrar todo el código de su diseño personalizado –

+0

@TheDimasig, acabo de actualizar mi pregunta, por favor revise :) – Freewind

Respuesta

2

Supongo que en su método onMeasure se olvida de llamar a Measure en todas las vistas secundarias, incluido su ImageView. Usted debe ir a través de todos los puntos de vista a su hijo y llame onMeasure en ellos algo como esto:

for (int i = 0; i < getChildCount(); i++) { 
     getChildAt(i).measure(....); 
    } 
+0

Acabo de leer la fuente de 'FrameLayout',' onMeasure' y 'onLayout' parece bastante complicado, ¿hay una manera simple de hacer esto? – Freewind

+0

En lugar de anular todo el cuerpo del método y setDimension() intenta llamar a super.onMeasure (widthMeasureSpec * 0.5, heightMeasureSpec) con tus parámetros. Esta solución puede ser necesaria para anular onLayout también de esta manera –

+0

Intenté 'widthMeasureSpec * 0.5', pero el tamaño final no se ve como se esperaba. No puedo entenderlo, ¿podrías darme un ejemplo de trabajo cuando tienes tiempo? – Freewind

7

No hay puntos de vista del niño, ya que no reemplaza el método onMeasure correctamente. Usted puede dejar que la superclase implementar la lógica (por lo que se le muestra los puntos de vista del niño) y luego reiniciar el ancho y la altura calculada para MyFrameLayout:

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    // let the super class handle calculations 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    // set again the dimensions, this time calculated as we want 
    setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight()/2); 
    // this is required because the children keep the super class calculated dimensions (which will not work with the new MyFrameLayout sizes) 
    final int count = getChildCount(); 
    for (int i = 0; i < count; i++) { 
     final View v = getChildAt(i); 
     // this works because you set the dimensions of the ImageView to FILL_PARENT   
     v.measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(), 
       MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
       getMeasuredHeight(), MeasureSpec.EXACTLY)); 
    } 
} 

Si ese diseño informados no es su diseño completo, entonces mi código podría no funcionar

14

La forma más sencilla es cambiar el measurespec en onMeasure, pero todavía llaman súper:

@Override 
protected void onMeasure(int widthMeasureSpec, 
        int heightMeasureSpec) { 
    int width = MeasureSpec.getSize(widthMeasureSpec); 
    int height = (int) (width * 0.5); 
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
} 

esta manera se obtiene las dimensiones que desee, pero no tiene que medir manualmente los niños.

+1

Puedo confirmar que funciona. Sin llamar a super.onMeasure(), ¡las vistas secundarias no estaban visibles! –

+0

muchas gracias, he leído mucho debate, ¡esta es la única respuesta válida para hacer que los niños cambien de tamaño con el diseño de los padres! – Giova

Cuestiones relacionadas