Android | 获取ViewGroup的所有子元素

32 android

getChildAt(i)on只获取a的直接子节点ViewGroup,是否可以在不进行嵌套循环的情况下访问所有子节点?

MH.*_*MH. 46

在撰写此答案时,接受的答案存在缺陷,因为它的结果中将包含重复内容.

对于那些在递归时遇到麻烦的人来说,这是一个非递归的替代方案.你可以获得奖励积分,这也是另一个答案的深度优先方法的广度优先搜索替代品.

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;
}
Run Code Online (Sandbox Code Playgroud)

一些快速测试(没有正式的)表明这种替代方案也更快,尽管这很可能与ArrayList另一个答案创建的新实例的数量有关.此外,结果可能会根据视图层次结构的垂直/水平方式而有所不同.


Rag*_*ood 40

(来源)

如果你想获得所有子视图以及子视图中的视图ViewGroups,你必须递归地执行它,因为API中没有提供开箱即用的功能.

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;
}
Run Code Online (Sandbox Code Playgroud)

这将为您提供一个ArrayList,其中包含层次结构中的所有视图,然后您可以迭代它们.

本质上,如果代码在层次结构中找到另一个ViewGroup,则此代码会调用自身,然后返回要添加到较大ArrayList的ArrayList.

  • 只要`ViewGroup`封装了另一个具有多个子节点的`ViewGroup`,您的代码就会保证在结果集中有重复.我会留给你弄清楚原因.你很接近,虽然结果中存在所有视图,但它也包含欺骗.也许这就是你的[复制粘贴](http://stackoverflow.com/a/11263152/1029225)?;) (9认同)