8

Actualmente estoy desarrollando una aplicación de tableta que usa intensamente el widget ViewPager. También obtuve múltiples Viewpagers en la pantalla a la vez.Detener Android desde Layouting todas mis vistas

Ahora estoy experimentando el siguiente problema: Si un ViewPager se desplaza a la página siguiente/anterior, (por supuesto) tiene que volver a calcular su diseño y agregar/eliminar vistas. Me di cuenta de que el requestLayout llama hasta la parte superior de la jerarquía de vista, por lo tanto, invalidar TODOS de mis vistas en la pantalla de la tableta (que son muchas). Esto es muy costoso.

Mi pregunta ahora es: ¿existe la posibilidad de implementar un marco alrededor del ViewPager la que hace el diseño inicial y luego no se propaga solicitudes esquemas de trazado de la vista Jerarquía que sé que después de la disposición inicial, el marco se mantiene del mismo tamaño y no cambiará.

Se me ocurrió el siguiente Marco, pero no funciona bastante bien, porque no funciona el 100% del tiempo.

public class MyFrame extends FrameLayout 
{ 
    // VARIABLE CONTROLLING THE DISPATCH OF THE LAYOUT 
    // REQUEST UP THE VIEW HIERARCHY 
    private boolean doLayout = true; 

    public MyFrame(Context context) 
    { 
     super(context); 
     doLayout = true; 
    } 

    @Override 
    public void requestLayout() 
    { 
     if (doLayout) // DO THE LAYOUT REQUEST UP TO THE TOP 
      super.requestLayout(); 
     else 
     { 
      // JUST MEASURE MYSELF AND MY CHILDREN 
      measure(MeasureSpec.getMode(MeasureSpec.AT_MOST), 
      MeasureSpec.getMode(MeasureSpec.AT_MOST)); 
      layout(getLeft(), getTop(), getRight(), getBottom()); 
     } 
     doLayout = false; 
    } 
} 

¡Gracias por cualquier consejo!

Respuesta

0

Realmente me gustaría poder decirte que hay una mejor manera, pero no creo que exista. Si ViewPager está de hecho agregando/eliminando vistas, su diseño será continuamente destruido, aunque no lo sea, podría ser. Es una suposición vaga que los contenidos pueden cambiar (invalidando así hacia arriba), y depende de nosotros los complicados programas para eliminar algunas de esas suposiciones.

Si puede asegurarse de que los límites de FrameLayout nunca cambien, no hay nada de malo en sobrescribir requestLayout en absoluto.

4

Sé que la pregunta es un poco vieja, pero mi respuesta podría ayudar a otra persona como su pregunta y la respuesta de Colin me ayudó.

Tengo exactamente el mismo problema que usted. Y hay dos soluciones para eso. Primero debe asegurarse de que su ViewPager tenga * layout_width * y * layout_height * establecido en * match_parent *, y que la jerarquía de vistas esté organizada de tal forma que Android no llegue a la conclusión de que necesita volver a diseñar cualquiera de los diseños principales de ViewPager. Por ejemplo, supongamos que tiene un RelativeLayout con dos vistas de tamaños fijos uno debajo de otro y un ViewPager debajo de la segunda vista. En este caso, cualquier cambio en ViewPager se propagará al diseño principal. Sin embargo, si coloca esas dos vistas de tamaño fijo y ViewPager en LinearLayout esto no sucederá, ninguna solicitud de diseño se propagará más allá de ViewPager. Lo que es aún mejor, la solicitud de diseño en una página de ViewPager tampoco se propagará a otras páginas.

La segunda solución (en realidad es más la segunda parte de la solución) corre a su FrameLayout, pero modificado como sigue:

public class LayoutStopperFrameLayout extends FrameLayout { 

    private boolean doLayout; 

    public LayoutStopperFrameLayout(Context context) { 
     super(context); 
     doLayout = true; 
    } 

    public LayoutStopperFrameLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     doLayout = true; 
    } 

    public LayoutStopperFrameLayout(Context context, AttributeSet attrs, 
      int defStyle) { 
     super(context, attrs, defStyle); 
     doLayout = true; 
    } 

    public void setPropagateRequestLayout(boolean doLayout) { 
     this.doLayout = doLayout; 
    } 

    @Override 
    public void requestLayout() { 
     if (doLayout) { 
      // DO THE LAYOUT REQUEST UP TO THE TOP 
      super.requestLayout(); 
     } 
    } 
} 

En mi solicitud llamo setPropagateRequestLayout() en el fragmento onStart y métodos OnStop a activar y desactivar las solicitudes de diseño, respectivamente.