如何在根布局中一般检索某种类型的所有 children?

How to generically retrieve all children of a certain type in a root layout?

我的问题的意思(如果我表述含糊,因为我找不到问题的答案)是采用根布局,获取该布局的所有 children,然后执行任何指定类型实例的回调。

现在,我可以用一种固定的方式轻松地做到这一点,方法是像...

RelativeLayout root = (RelativeLayout) findViewById(R.id.root_layout);
    for(int i = 0; i <= root.getChildCount(); i++){
        View v = root.getChildAt(i);
        if(v instanceof CustomLayout){
            // Do Callback on view.
        }
    }

事实是,我想让它更通用。我应该能够使用任何布局,并检查它是否是任何布局的实例。特别是,我希望它足够通用以用于任何事物(如果可能的话)。当然,我不介意仅仅满足于布局。

我想构建这些 children 和 return 的集合,如果可能的话,它们是同一类型的。我已经有很长一段时间没有做 Java 所以我很生疏,但我正在考虑使用反射来完成这个。这完全可能吗?

如果我通过我想要的类型的class,可以吗?

编辑:

之前没看到dtann的回答,肯定是漏了,不过是我自己做的,和他的很像。我的实现遵循了这个

public static abstract class CallbackOnRootChildren<T> {
        @SuppressWarnings("unchecked")
        public void callOnChildren(Class<T> clazz, ViewGroup root) {
            for(int i = 0; i < root.getChildCount(); i++){
                View v = root.getChildAt(i);
                if(v instanceof ViewGroup){
                    callOnChildren(clazz, (ViewGroup) v);
                }
                if(clazz.isAssignableFrom(v.getClass())){
                    // The check to see if it is assignable ensures it's type safe.
                    onChild((T) v);
                }
            }
        }

        public abstract void onChild(T child);
    }

不同之处在于我的依赖于回调等等,但总体上是相同的概念。

对此没有通用的方法。如果有人这样做,就会简单地做类似的事情。

视图组中的视图保存在像(源代码)这样​​的字段中:

// Child views of this ViewGroup
private View[] mChildren;
// Number of valid children in the mChildren array, the rest should be null or not
// considered as children
private int mChildrenCount;

See documentation

试试下面的代码:

public <T> List<T>  getViewsByClass(View rootView, Class<T> targetClass) {
    List<T> items = new ArrayList<>();
    getViewsByClassRecursive(items,rootView,targetClass);
    return items;
}

private void getViewsByClassRecursive(List items, View view, Class clazz) {
    if (view.getClass().equals(clazz)) {
        Log.d("TAG","Found " + view.getClass().getSimpleName());
        items.add(view);
    }

    if (view instanceof ViewGroup) {
        ViewGroup viewGroup = (ViewGroup)view;
        if (viewGroup.getChildCount() > 0) {
            for (int i = 0; i < viewGroup.getChildCount(); i++) {
                getViewsByClassRecursive(items, viewGroup.getChildAt(i), clazz);
            }
        }
    }
}

调用getViewsByClass并传入根布局和目标class。您应该收到作为目标 class 实例的所有视图的列表。如果它也是目标 class 的一个实例,这将包括根布局本身。此方法将搜索根布局的整个视图树。