studio layout_width layout_weight gridlayout examples ejemplos ejemplo dinamico android

layout_width - Android | Obtener todos los elementos hijos de un ViewGroup



layout dinamico android (5)

( source )

Si desea obtener todas las vistas secundarias, así como las vistas dentro de los ViewGroups vistas infantiles, debe hacerlo de forma recursiva, ya que no hay ninguna disposición en la API para hacerlo de forma ViewGroups .

private ArrayList<View> getAllChildren(View v) { if (!(v instanceof ViewGroup)) { ArrayList<View> viewArrayList = new ArrayList<View>(); viewArrayList.add(v); return viewArrayList; } ArrayList<View> result = new ArrayList<View>(); ViewGroup viewGroup = (ViewGroup) v; for (int i = 0; i < viewGroup.getChildCount(); i++) { View child = viewGroup.getChildAt(i); ArrayList<View> viewArrayList = new ArrayList<View>(); viewArrayList.add(v); viewArrayList.addAll(getAllChildren(child)); result.addAll(viewArrayList); } return result; }

Esto le dará una lista de arreglos con todas las vistas en la jerarquía que luego puede iterar.

Esencialmente, este código se llama a sí mismo si encuentra otro ViewGroup en la jerarquía, y luego devuelve una ArrayList para agregarse a la ArrayList más grande.

getChildAt(i) on solo obtiene los hijos directos de ViewGroup , ¿es posible acceder a todos los hijos sin hacer bucles anidados?


Al momento de escribir esta respuesta, la respuesta aceptada es errónea, ya que contendrá duplicados en su resultado.

Para aquellos que tienen problemas para envolver su cabeza en torno a la recursión, aquí hay una alternativa no recursiva. Obtendrá puntos de bonificación por darse cuenta de que esto también es una alternativa de búsqueda en primer lugar al enfoque de primero en profundidad de la otra respuesta.

private List<View> getAllChildrenBFS(View v) { List<View> visited = new ArrayList<View>(); List<View> unvisited = new ArrayList<View>(); unvisited.add(v); while (!unvisited.isEmpty()) { View child = unvisited.remove(0); visited.add(child); if (!(child instanceof ViewGroup)) continue; ViewGroup group = (ViewGroup) child; final int childCount = group.getChildCount(); for (int i=0; i<childCount; i++) unvisited.add(group.getChildAt(i)); } return visited; }

Un par de pruebas rápidas (nada formal) sugieren que esta alternativa también es más rápida, aunque es probable que tenga que ver con la cantidad de instancias nuevas de ArrayList crea la otra respuesta. Además, los resultados pueden variar según la vertical / horizontal de la jerarquía de vistas.


Aquí está mi solución (recursiva) que imprime la jerarquía de esta manera:

android.widget.LinearLayout children:2 id:-1 android.view.View id:2131624246 android.widget.RelativeLayout children:2 id:2131624247 android.support.v7.widget.AppCompatTextView id:2131624248 android.support.v7.widget.SwitchCompat id:2131624249 public static String getViewHierarcy(ViewGroup v) { StringBuffer buf = new StringBuffer(); printViews(v, buf, 0); return buf.toString(); } private static String printViews(ViewGroup v, StringBuffer buf, int level) { final int childCount = v.getChildCount(); v.getId(); indent(buf, level); buf.append(v.getClass().getName()); buf.append(" children:"); buf.append(childCount); buf.append(" id:"+v.getId()); buf.append("/n"); for (int i = 0; i < childCount; i++) { View child = v.getChildAt(i); if ((child instanceof ViewGroup)) { printViews((ViewGroup) child, buf, level+1); } else { indent(buf, level+1); buf.append(child.getClass().getName()); buf.append(" id:"+child.getId()); buf.append("/n"); } } return buf.toString(); } private static void indent(StringBuffer buf, int level) { for (int i = 0; i < level; i++) { buf.append(" "); } }


He reimplementado este método de forma recursiva. No estoy seguro de que sea más rápido que los MH, pero al menos no tiene duplicados.

private List<View> getAllViews(View v) { if (!(v instanceof ViewGroup) || ((ViewGroup) v).getChildCount() == 0) // It''s a leaf { List<View> r = new ArrayList<View>(); r.add(v); return r; } else { List<View> list = new ArrayList<View>(); list.add(v); // If it''s an internal node add itself int children = ((ViewGroup) v).getChildCount(); for (int i=0;i<children;++i) { list.addAll(getAllViews(((ViewGroup) v).getChildAt(i))); } return list; } }

La respuesta de MH incluye la vista principal que se le da al método, así que creé este método auxiliar (que es el que debe llamarse).

Quiero decir, si llama a este método en un TextView (que no tiene hijos), devuelve 0 en lugar de 1.

private List<View> getAllChildren(View v) { List list = getAllViews(v); list.remove(v); return list; }

TLDR: para contar todos los hijos, copie y pegue ambos métodos, llame a getAllChildren ()


No sé si es bueno o no. Simplemente anule el método onViewAdded (View child) y simplemente agregue las vistas en la List<View> Dale pensamientos. Por los docs . Esto es útil cuando estás escribiendo un grupo de vistas personalizado

Se llama cuando se agrega un nuevo hijo a este ViewGroup. Las anulaciones siempre deben llamar a super.onViewAdded.

@Override public void onViewAdded(View child) { super.onViewAdded(child); views.add(child);//add in list and then use it later }