Перечислять / Итерировать все представления в действии?

Есть ли способ перебрать все виды в вашей деятельности? Что-то вроде:

  Итератор it = getViewIterator ();
 ...

Это вообще существует?

Solutions Collecting From Web of "Перечислять / Итерировать все представления в действии?"

Если у вас есть все ваши представления в LinearLayout или другом container который расширяет ViewGroup вы можете использовать функции getChildCount() и getChildAt(int) и перебирать все
Содержащиеся виды.

Надеюсь это поможет.

Предполагая, что «все взгляды в вашей деятельности» вы подразумеваете каждое представление в иерархии, в Android нет такого Iterator или чего-либо еще, что позволяет вам перебирать все виды.

ViewGroup есть методы getChildCount и getChildAt , но они касаются прямых дочерних элементов ViewGroup . Таким образом, вам нужно будет посетить каждого ребенка и проверить, является ли это самой ViewGroup , и так далее. Короче говоря, я хотел, чтобы такая функциональность находила все представления, соответствующие конкретному тегу (findViewWithTag возвращает только первый), поэтому я написал несколько классов для этого. Вот как вы можете перебирать каждый вид в Layout :

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

Активность Обычно содержит один основной контейнер макетов, в котором размещены все остальные виды. Используя ссылку Main Layout Container. Пройдите через своего ребенка (используйте getChild (postion), getchildcount () и т. Д.). И если какой-либо ребенок является контейнером, тогда примените к нему ту же самую функцию. Это похоже на перемещение древовидной структуры

Вот мой пример, основанный на ответе Гарри Джой . Он выполняет итерацию по всем иерархиям родительской ViewGroup чтобы увидеть, является ли какое-либо из видов в ней внутри 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; } 

Если вам действительно нужен итератор, в api нет ничего подобного. Вы должны будете написать свой собственный, который построен на основе логики, которую предлагает Гарри Джой и Джаванатор.

Если вы хотите избежать уродливости for (int i = 0; ….), вы можете использовать статическую оболочку

 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); } }; } }; } } 

И использовать его так

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

Конечно, это немного менее эффективно, поскольку вы создаете новый объект Iteratable каждый раз, когда выполняете итерацию, но вы можете построить на нем более эффективный алгоритм, если хотите.