2011-02-02 8 views
13

¿Hay alguna forma de recorrer todas las vistas de tu actividad? Algo así como:¿Enumerar/iterar todas las vistas en la actividad?

Iterator it = getViewIterator(); 
... 

Does this exist at all?

+1

Me pregunto, ¿por qué quieres eso? –

+1

Sí, ¿cuál es el requisito para hacer esto ...? – Javanator

+1

Consulte http://code.google.com/p/android/issues/detail?id=8488, mi código está cerca de la parte inferior – swinefeaster

Respuesta

17

If you have all your Views in a LinearLayout o un container otra que se extiende ViewGroup puede utilizar las funciones getChildCount() y getChildAt(int) e iterar a través de todos los puntos de vista
contenida.

Espero que esto ayude.

+0

Sí, esto funciona a la perfección. ¡Gracias! Tuve que anular mis funciones setContentView() en mi actividad base para poder almacenar un puntero en el Grupo de Vista raíz y luego iterarlo a través de su método. – swinefeaster

+1

Alternativa a la anulación de setContentView, podría haber suministrado una identificación al contenedor más externo en la vista que se está inflando y luego haberla agarrado con findViewById(). –

1

Actividad Generalmente contiene un contenedor de diseño principal en el que se colocan todas las demás vistas. Usando la referencia del contenedor de diseño principal. Atraviesa su hijo (use getChild (postion), getchildcount(), etc.). y si algún niño es un contenedor, entonces aplique la misma función en él ... Esto es algo así como atravesar una estructura de árbol

0

Si realmente necesita un iterador, no hay nada de eso disponible en la API. Tendrás que escribir el tuyo que esté construido sobre la lógica que sugieren Harry Joy y Javanator.

7

Asumiendo por "todas las vistas en su Actividad" se refiere a cada vista en la jerarquía, no hay tal Iterator ni nada en Android que le permita iterar sobre todas las vistas.

ViewGroup s tienen getChildCount y getChildAt métodos, pero están sobre niños directos del ViewGroup. Por lo tanto, debería visitar a todos los niños y verificar si es un ViewGroup, y así sucesivamente. Para resumir, quería esa funcionalidad para encontrar todas las vistas que coinciden con una etiqueta específica (findViewWithTag solo devuelve la primera), así que escribí a few classes para lograrlo. He aquí cómo usted puede iterar sobre cada punto de vista bajo un Layout:

LayoutTraverser.build(new LayoutTraverser.Processor() { 
    @Override 
    public void process(View view) { 
    // do stuff with the view 
    } 
}).traverse(viewGroup); 
+0

Enlace a la página del autor con el código fuente de esta clase: http://android-wtf.com/2013/06/how-to-easily-traverse-any-view-hierarchy-in-android/ – ruX

1

Aquí está mi ejemplo, basándose en Harry Joy's answer. Itera a través de todas las jerarquías de los padres ViewGroup para ver si alguna de las vistas en cualquier lugar dentro de ella son un Button:

private boolean doesViewGroupContainButton(ViewGroup parentView) { 

     int numChildViews = parentView.getChildCount(); 
     for (int i = 0; i < numChildViews; i++) { 
      View childView = parentView.getChildAt(i); 
      if (childView instanceof ViewGroup) { 
       if (doesViewContainButton((ViewGroup)childView)) { 
        return true; 
       } 
      } 
      else if (childView instanceof Button) { 
       return true; 
      } 
     } 
     return false; 

    } 
0

Si se quiere evitar la fea for (int i = 0; ....) se puede utilizar un envoltorio estática

public class Tools 
{ 
    public static Iterable<View> getChildViews(final ViewGroup view) 
    { 
     return new Iterable<View>() 
     { 
      int i = -1; 

      @NonNull 
      @Override 
      public Iterator<View> iterator() 
      { 
       return new Iterator<View>() 
       { 
        int i = -1; 
        @Override 
        public boolean hasNext() 
        { 
         return i < view.getChildCount(); 
        } 

        @Override 
        public View next() 
        { 
         return view.getChildAt(++i); 
        } 
       }; 
      } 

     }; 
    } 
} 

y utilizarlo como tal

for (View view : Tools.getChildViews(viewGroup)) 

por supuesto, esto es un poco menos eficiente ya que son creat de un nuevo objeto Iteratable cada vez que itere, pero puede construir sobre este un algoritmo más eficiente si lo desea.

Cuestiones relacionadas