getChildAt(i)
on gets only the direct children of a ViewGroup
, is it possible to access to all children without doing nested loops?

- 6,511
- 13
- 49
- 53
-
http://stackoverflow.com/a/18980154/1093872 far more optimal sollution than the answers. (Creates no object garbage, runs faster, simpler) – Adam Toth Aug 02 '14 at 20:03
10 Answers
At the time of writing this answer, the accepted answer is flawed in that it will contains duplicates in its result.
For those who have trouble wrapping their head around recursion, here's a non-recursive alternative. You get bonus points for realizing this is also a breadth-first search alternative to the depth-first approach of the other answer.
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;
}
A couple of quick tests (nothing formal) suggest this alternative is also faster, although that has most likely to do with the number of new ArrayList
instances the other answer creates. Also, results may vary based on how vertical/horizontal the view hierarchy is.

- 45,303
- 10
- 103
- 116
(source)
If you want to get all the child views, as well as the views within children ViewGroups
, you must do it recursively, since there is no provision in the API to do this out of the box.
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;
}
This will give you an ArrayList with all the Views in the hierarchy which you can then iterate over.
Essentially, this code call itself if it finds another ViewGroup in the hierarchy, and then returns an ArrayList to be added to the bigger ArrayList.

- 1
- 1

- 81,899
- 22
- 187
- 195
-
9Your code is guaranteed to have duplicates in the result set as soon as a `ViewGroup` encapsulates another `ViewGroup` with more than one child. I'll leave it up to you to figure out why. You're close, and although all views are present in the result, it also contains dupes. Perhaps that's what you get for [copy-pasting](http://stackoverflow.com/a/11263152/1029225)? ;) – MH. Sep 07 '13 at 02:55
-
wouldn't this code have ass many ViewGroup duplicates as views has the ViewGroups? since viewArrayList.add(v) (which represents the ViewGroup is called in each iteration. – LuisE Oct 30 '16 at 17:57
For those using androidx and kotlin
1 - Iterate through ViewGroup
using forEach{}
If you want to iterate through all childViews, you can use predefined kotlin extension forEach
in any ViewGroup. Example:
yourViewGroup.forEach{ childView ->
// do something with this childView
}
2 - Return a list of childViews using .children.toList
in a ViewGroup
To return a list of Views
, you can use function children
to return a Sequence
and then use toList()
to transform it to a List
. Example:
val yourChildViewsList: List<View> = yourViewGroup.children.toList()

- 496
- 5
- 4
-
1These functions only return the views that are currently on screen (and thus inflated?) and not items that are off-screen – Clocker Oct 19 '21 at 04:59
I've reimplemented this method in a recursive way. Not sure it's faster than MH's, but at least it has no duplicates.
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;
}
}
MH's answer includes the parent view which is being given to the method, so I created this auxiliary method (which is the one to be called).
I mean, if you call this method on a TextView (which has no children), it returns 0 instead of 1.
private List<View> getAllChildren(View v) {
List list = getAllViews(v);
list.remove(v);
return list;
}
TLDR: to count all children copy and paste both methods, call getAllChildren()

- 5,928
- 4
- 38
- 37
I don't know if its good or not.just override the onViewAdded(View child) method and just add the views in List<View>
.Give it thoughts.by the docs.This usefull when you are writing custom view group
Called when a new child is added to this ViewGroup. Overrides should always call super.onViewAdded.
@Override
public void onViewAdded(View child) {
super.onViewAdded(child);
views.add(child);//add in list and then use it later
}

- 2,286
- 3
- 18
- 25
I recently had the same issue and solved it using Kotlin's extension functions like this:
fun ViewGroup.getAllChildren(): List<View> {
val children = ArrayList<View>()
for (i in 0 until this.childCount) {
children.add(this.getChildAt(i))
}
return children
}

- 9,113
- 13
- 65
- 78

- 543
- 4
- 9
Maybe you can look at the Kotlin provided method ViewGroup.descendants
, other than writing your own recursively function code, you may use it, with document stated
Returns a Sequence over the child views in this view group recursively. This performs a depth-first traversal. A view with no children will return a zero-element sequence.

- 63
- 7
Here is my (recursive) solution that prints the hierarcy like this:
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(" ");
}
}

- 1,274
- 13
- 29
You can using Kotlin's extension functions Like ViewGroup.children
this method returns a Sequence over the child views in this view group.

- 896
- 11
- 18
To recursively search a ViewGroup for a specific view (I use TextView in this example).
ArrayList<TextView> textViews = new ArrayList<TextView>();
ArrayList<View> views = new ArrayList<View>(); // Temporarily stores views that should be checked for child views
views.add(ParentView); // Add the view you want to recursively scan for a type of view (instance of), Parent (Main ViewGroup)
// Get all TextViews within parent
int loopCount = 0;
while (views.size() > loopCount)
{
for (int i=0; i < ( (ViewGroup) views.get(loopCount)).getChildCount(); i++)
{
if ( ((ViewGroup) views.get(loopCount)).getChildAt(i) instanceof TextView )
{
textViews.add( (TextView) ((ViewGroup) views.get(loopCount)).getChildAt(i) );
}
else
{
views.add( ((ViewGroup) views.get(loopCount)).getChildAt(i) );
}
}
loopCount++;
}

- 69
- 1
- 5