Есть ли способ перебрать все виды в вашей деятельности? Что-то вроде:
Итератор it = getViewIterator (); ...
Это вообще существует?
Если у вас есть все ваши представления в 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 каждый раз, когда выполняете итерацию, но вы можете построить на нем более эффективный алгоритм, если хотите.