2011-09-22 10 views
5

He creado un diseño personalizado que amplía ViewGroup. Todo está funcionando bien y estoy obteniendo el diseño como se esperaba.ViewGroup finaliza el evento de inflar

que quieren cambiar dinámicamente un elemento en el diseño. Sin embargo, esto no funciona, ya que lo estoy llamando en Crear y hasta ese momento, el diseño completo no está realmente (dibujado) inflado en la pantalla y, por lo tanto, no tiene el tamaño real.

¿Hay algún evento que se puede utilizar para averiguar cuándo se realiza la inflación del diseño? Intenté en FinalInflate pero eso no funcionaría ya que Viewgroup tiene varias vistas y esto se llamaría varias veces.

Estoy pensando en crear una interfaz en la clase de diseño personalizado, pero no está seguro de cuándo disparar?

Respuesta

20

Si entiendo sus necesidades correctamente, un OnGlobalLayoutListener puede darle lo que usted necesitar.

View myView=findViewById(R.id.myView); 
    myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
      @Override 
      public void onGlobalLayout() { 
       //At this point the layout is complete and the 
       //dimensions of myView and any child views are known. 
      } 
     }); 
+0

He estado usando esto por algún tiempo para ajustar el tamaño de texto en la vista de texto, nunca supe que esto también se puede usar para ViewGroup. ¡Gracias por la ayuda! – PravinCG

2

Por lo general, al crear un diseño personalizado que se extiende View o ViewGroup, usted tiene que anular protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) y protected void onLayout(boolean changed, int left, int top, int right, int bottom). Estos se llaman durante el proceso de inflación para obtener la información de tamaño y ubicación relacionada con la vista. También, posteriormente, si se está extendiendo ViewGroup has de ponerle measure(int widthMeasureSpec, int heightMeasureSpec) y layout(int l, int t, int r, int b) en cada punto de vista del niño que contiene. (se llama a measure() en Measure() y layout() se invoca onLayout()).

De todos modos, en onMeasure(), por lo general, hacer algo como esto.

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
{ 
    // Gather this view's specs that were passed to it 
    int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
    int widthSize = MeasureSpec.getSize(widthMeasureSpec); 
    int heightMode = MeasureSpec.getMode(heightMeasureSpec); 
    int heightSize = MeasureSpec.getSize(heightMeasureSpec); 

    int chosenWidth = DEFAULT_WIDTH; 
    int chosenHeight = DEFAULT_HEIGHT; 
    if(widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.EXACTLY) 
     chosenWidth = widthSize; 
    if(heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.EXACTLY) 
     chosenHeight = heightSize; 

    setMeasuredDimension(chosenWidth, chosenHeight); 

    *** NOW YOU KNOW THE DIMENSIONS OF THE LAYOUT *** 
} 

En onLayout() que obtener las coordenadas en píxeles reales de la vista, para que pueda obtener el tamaño físico de este modo:

@Override 
protected void onLayout(boolean changed, int left, int top, int right, int bottom) 
{ 
    // Android coordinate system starts from the top-left 
    int width = right - left; 
    int height = bottom - top; 
} 
+0

Gracias por la respuesta. He hecho todo lo que ha prescrito mi consulta, ya que el valor va a ser dinámico, ¿cómo paso esa información de la Actividad y más importante cuando (evento)? – PravinCG

+1

Ok. Pensé que estabas cambiando la vista dinámicamente dentro de la vista. Si ese fuera el caso, puede usar esos dos métodos para conocer sus coordenadas (incluso antes de que esté a la vista). Otra opción puede ser usar 'onWindowFocusChanged()' que es parte de 'Activity'. De acuerdo con la documentación 'Llamado cuando la ventana actual de la actividad gana o pierde el foco. Este es el mejor indicador de si esta actividad es visible para el usuario. La implementación predeterminada borra el estado de seguimiento de clave, por lo que siempre debe invocarse. 'Lo he usado para determinar cuándo se veía una ventana (por lo tanto inflado). – DeeV

+0

+1, gracias por la respuesta. El método anterior no es la manera confiable de hacerlo aunque podría funcionar en algunos casos. – PravinCG

Cuestiones relacionadas