探索 Android 中的视图树
Exploring the view tree in Android
它可能有点抽象,但我想知道你们中的一些人是否有解决该问题的合适方法:
我的布局很复杂,我需要找到某种视图类型的所有实例。
我的解决方案很少,但我发现其中 none 个是完美的,我想知道是否有其他方法或方法可以改进它们。
我的第一个选择
我们可以使用 getChildCount()
和 getChildAt()
在视图树中进行迭代,然后像许多 SO 答案一样使用 instanceof
检查。
for (int i = 0; i<parentContainer.getChildCount(); i++){
View child = getChildAt(i);
if (child instanceof BlaBla){
// Do something wonderful
}
}
这是非常低效的,因为我在很多地方都有这些实例,特别是在嵌套的地方,所以我需要使这个方法递归。
我的第二个选择
将使用动态标签或 ID 并使用 findViewById
或 findViewWithTag
。但问题是它需要配置更多东西,并且一如既往地使软件更加复杂。
So my question is: how can I do a complete search in the view tree in
order to find all instances of a component without doing the search
myself (because it would be probably be very inefficient)? Is that
somehow possible?
因此,我不确定第二个选项是否可行,因为在这种情况下,您需要在运行时创建此视图并分配一些生成的 ID 和一些位掩码以便稍后识别它们。如果要从布局创建视图,您最终会遍历树视图并分配这些特殊 ID,这几乎符合第一个选项。
在我的项目中,我还必须动态地将颜色应用到某些视图,并且我在没有递归的情况下进行。模式如下:
ArrayList<View> views = new ArrayList<>();
views.add(getWindow().getDecorView());
do {
View v = views.remove(0);
if (v instanceof ViewGroup) {
ViewGroup group = (ViewGroup) v;
for (int i = 0; i < group.getChildCount(); i++) {
views.add(group.getChildAt(i));
}
}
if (v instanceof MyCustomView) {
//do whatever you need here
}
} while(!views.isEmpty());
所以你摆脱了使用递归并用自己的堆栈和迭代替换它。这个解决方案非常有效,特别是如果你可以跳过像 ListView、RecyclerView 这样的东西。
它可能有点抽象,但我想知道你们中的一些人是否有解决该问题的合适方法:
我的布局很复杂,我需要找到某种视图类型的所有实例。
我的解决方案很少,但我发现其中 none 个是完美的,我想知道是否有其他方法或方法可以改进它们。
我的第一个选择
我们可以使用 getChildCount()
和 getChildAt()
在视图树中进行迭代,然后像许多 SO 答案一样使用 instanceof
检查。
for (int i = 0; i<parentContainer.getChildCount(); i++){
View child = getChildAt(i);
if (child instanceof BlaBla){
// Do something wonderful
}
}
这是非常低效的,因为我在很多地方都有这些实例,特别是在嵌套的地方,所以我需要使这个方法递归。
我的第二个选择
将使用动态标签或 ID 并使用 findViewById
或 findViewWithTag
。但问题是它需要配置更多东西,并且一如既往地使软件更加复杂。
So my question is: how can I do a complete search in the view tree in order to find all instances of a component without doing the search myself (because it would be probably be very inefficient)? Is that somehow possible?
因此,我不确定第二个选项是否可行,因为在这种情况下,您需要在运行时创建此视图并分配一些生成的 ID 和一些位掩码以便稍后识别它们。如果要从布局创建视图,您最终会遍历树视图并分配这些特殊 ID,这几乎符合第一个选项。
在我的项目中,我还必须动态地将颜色应用到某些视图,并且我在没有递归的情况下进行。模式如下:
ArrayList<View> views = new ArrayList<>();
views.add(getWindow().getDecorView());
do {
View v = views.remove(0);
if (v instanceof ViewGroup) {
ViewGroup group = (ViewGroup) v;
for (int i = 0; i < group.getChildCount(); i++) {
views.add(group.getChildAt(i));
}
}
if (v instanceof MyCustomView) {
//do whatever you need here
}
} while(!views.isEmpty());
所以你摆脱了使用递归并用自己的堆栈和迭代替换它。这个解决方案非常有效,特别是如果你可以跳过像 ListView、RecyclerView 这样的东西。