好的,我有一个类似于以下示例的布局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。
按类型获得一堆孩子的最佳方法是什么?
答案 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)