Android:如何按类型查找视图

时间:2012-12-14 22:13:40

标签: android android-layout

好的,我有一个类似于以下示例的布局xml:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/tile_bg" >

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingTop="10dp" >

    <LinearLayout
        android:id="@+id/layout_0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <!-- view stuff here -->
    </LinearLayout>

    <!-- more linear layouts as siblings to this one -->

</LinearLayout>

我实际上有大约7个LinearLayout项目,每个项目的id都从layout_0等增加。我希望能够获得根LinearLayout下的所有LinearLayout项目。我是否需要在根目录上放置一个id并通过id找到所有其他ID,或者我可以按类型获取它们。

我用来夸大布局的代码是:

View view = (View) inflater.inflate(R.layout.flight_details, container, false);

我在某处读过你可以迭代ViewGroup的子节点,但这只是一个View。

按类型获得一堆孩子的最佳方法是什么?

7 个答案:

答案 0 :(得分:30)

这可以让你走上正轨。

LinearLayout rootLinearLayout = (LinearLayout) findViewById(R.id.rootLinearLayout);
int count = rootLinearLayout.getChildCount();
for (int i = 0; i < count; i++) {
    View v = rootLinearLayout.getChildAt(i);
    if (v instanceof LinearLayout) {
        ...
    }
}

答案 1 :(得分:3)

如果您知道布局的根元素是ViewGroup或其他布局等子类,则可以安全地将结果视图转换为LinearLayout

ViewGroup vg = (ViewGroup)view;

并根据需要使用。如果您知道总是只对根容器使用一种类型的布局,则可以转换为该类型,即:

LinearLayout vg = (LinearLayout)view;

答案 2 :(得分:1)

您应该向LinearLayout根添加一个ID:

<LinearLayout
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingTop="10dp" >

    <LinearLayout
        android:id="@+id/layout_0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <!-- view stuff here -->
    </LinearLayout>

    <!-- more linear layouts as siblings to this one -->

</LinearLayout>

然后像往常一样给整个布局充气:

View view = (View) inflater.inflate(R.layout.flight_details, container, false);

抓住你的根[{1}}:

LinearLayout

答案 3 :(得分:1)

将根视图作为此DFS方法的参数传递:

private List<LinearLayout> mArr = new ArrayList<LinearLayout>();

private void getLinearLayouts(ViewGroup parent) {
    int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        View child = parent.getChildAt(i);
        if (child instanceof ViewGroup) {
            getLinearLayouts((ViewGroup) child);
            if (child instanceof LinearLayout)
                mArr.add((LinearLayout) child);
        }
    }
}

答案 4 :(得分:1)

我只是想添加一个更通用的,但你必须记住,这是一个很重要的方法。

无论如何,这是代码:

private static <T extends View> ArrayList<T> getChildrenOfParentWithClass(ViewGroup parent, Class<T> clazz)
{
    ArrayList<T> children = new ArrayList<>();

    int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++)
    {
        View child = parent.getChildAt(i);
        if (child instanceof ViewGroup)
        {
            children.addAll(getChildrenOfParentWithClass((ViewGroup) child, clazz));
            if (child.getClass().equals(clazz))
            {
                children.add((T) child);
            }
        }
    }

    return children;
}

答案 5 :(得分:0)

喜欢@ChristopheCVB的回答,但也支持继承(参见tClass.isInstance(child))。

public static <T extends View> ArrayList<T> getViewsByType(ViewGroup root, Class<T> tClass) {
    final ArrayList<T> result = new ArrayList<>();
    int childCount = root.getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = root.getChildAt(i);
        if (child instanceof ViewGroup)
            result.addAll(getViewsByType((ViewGroup) child, tClass));

        if (tClass.isInstance(child))
            result.add(tClass.cast(child));
    }
    return result;
}

一个简单的用法示例:

ArrayList<TextView> TextViews = getViewsByType(rootLayout, TextView.class);

感谢接受的答案。

答案 6 :(得分:0)

Mir-Ismaili的科特林版答案:

fun <T : View> ViewGroup.getViewsByType(tClass: Class<T>): List<T> {
  return mutableListOf<T?>().apply {
    for (i in 0 until childCount) {
      val child = getChildAt(i)
      (child as? ViewGroup)?.let {
        addAll(child.getViewsByType(tClass))
      }
      if (tClass.isInstance(child))
        add(tClass.cast(child))
    }
  }.filterNotNull()
}

例如使用myViewGroup.getViewsByType(EditText::class.java)

对其进行调用