Android - get children inside a View?

AndroidView

Android Problem Overview


Given a View how can I get the child views inside it?

So I have a custom View and debugger shows that under mChildren there are 7 other views. I need a way to access these views but it doesn't seem like there is a public API to do this.

any suggestions?

EDIT:

My custom view inherits from AdapterView

Android Solutions


Solution 1 - Android

for(int index = 0; index < ((ViewGroup) viewGroup).getChildCount(); index++) {
    View nextChild = ((ViewGroup) viewGroup).getChildAt(index);
}

Will that do?

Solution 2 - Android

If you not only want to get all direct children but all children's children and so on, you have to do it recursively:

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 vg = (ViewGroup) v;
    for (int i = 0; i < vg.getChildCount(); i++) {

        View child = vg.getChildAt(i);

        ArrayList<View> viewArrayList = new ArrayList<View>();
        viewArrayList.add(v);
        viewArrayList.addAll(getAllChildren(child));

        result.addAll(viewArrayList);
    }
    return result;
}

To use the result you could do something like this:

    // check if a child is set to a specific String
    View myTopView;
    String toSearchFor = "Search me";
    boolean found = false;
    ArrayList<View> allViewsWithinMyTopView = getAllChildren(myTopView);
    for (View child : allViewsWithinMyTopView) {
        if (child instanceof TextView) {
            TextView childTextView = (TextView) child;
            if (TextUtils.equals(childTextView.getText().toString(), toSearchFor)) {
                found = true;
            }
        }
    }
    if (!found) {
        fail("Text '" + toSearchFor + "' not found within TopView");
    }

Solution 3 - Android

You can always access child views via View.findViewById() http://developer.android.com/reference/android/view/View.html#findViewById(int).

For example, within an activity / view:

...
private void init() {
  View child1 = findViewById(R.id.child1);
}
...

or if you have a reference to a view:

...
private void init(View root) {
  View child2 = root.findViewById(R.id.child2);
}

Solution 4 - Android

I'm just going to provide this answer as an alternative @IHeartAndroid's recursive algorithm for discovering all child Views in a view hierarchy. Note that at the time of this writing, the recursive solution 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 recursive solution.

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.

Cross-posted from: https://stackoverflow.com/questions/18668897/android-get-all-children-elements-of-a-viewgroup

Solution 5 - Android

Here is a suggestion: you can get the ID (specified e.g. by android:id="@+id/..My Str..) which was generated by R by using its given name (e.g. My Str). A code snippet using getIdentifier() method would then be:

public int getIdAssignedByR(Context pContext, String pIdString)
{
    // Get the Context's Resources and Package Name
	Resources resources = pContext.getResources();
    String packageName  = pContext.getPackageName();

    // Determine the result and return it
    int result = resources.getIdentifier(pIdString, "id", packageName);
	return result;
}

From within an Activity, an example usage coupled with findViewById would be:

// Get the View (e.g. a TextView) which has the Layout ID of "UserInput"
int rID = getIdAssignedByR(this, "UserInput")
TextView userTextView = (TextView) findViewById(rID);

Solution 6 - Android

As an update for those who come across this question after 2018, if you are using Kotlin, you can simply use the Android KTX extension property ViewGroup.children to get a sequence of the View's immediate children.

Solution 7 - Android

This method takes all views inside a layout, this is similar to Alexander Kulyakhtin's answer. The difference is, it accepts any type of parent layouts & returns an Array List of views.

public List<View> getAllViews(ViewGroup layout){
        List<View> views = new ArrayList<>();
        for(int i =0; i< layout.getChildCount(); i++){
            views.add(layout.getChildAt(i));
        }
        return views;
}

Solution 8 - Android

In order to refresh a table layout (TableLayout) I ended up having to use the recursive approach mentioned above to get all the children's children and so forth.

My situation was somewhat simplified because I only needed to work with LinearLayout and those classes extended from it such as TableLayout. And I was only interested in finding TextView children. But I think it's still applicable to this question.

The final class runs as a separate thread, which means it can do other things in the background before parsing for the children. The code is small and simple and can be found at github: https://github.com/jkincali/Android-LinearLayout-Parser

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionaryaxtView Question on Stackoverflow
Solution 1 - AndroidAlexander KulyakhtinView Answer on Stackoverflow
Solution 2 - AndroidJoachimRView Answer on Stackoverflow
Solution 3 - AndroidjonsonView Answer on Stackoverflow
Solution 4 - AndroidMH.View Answer on Stackoverflow
Solution 5 - AndroidvanangelovView Answer on Stackoverflow
Solution 6 - AndroidChuck SteinView Answer on Stackoverflow
Solution 7 - AndroidNJY404View Answer on Stackoverflow
Solution 8 - AndroidjkincaliView Answer on Stackoverflow