在Android中探索视图树

时间:2016-03-17 12:41:02

标签: android android-view

这可能有点抽象,但我想知道你们中的一些人是否有一个很好的解决方案来解决这个问题:

我的布局很复杂,我需要找到某种类型视图的所有实例。

我的解决方案很少,但我发现它们都不完美,我想知道是否有其他方法或方法可以改善它们。

我的第一个选择

我们可以使用getChildCount()getChildAt()在视图树中进行迭代,然后像许多SO答案一样检查instanceof

for (int i = 0; i<parentContainer.getChildCount(); i++){
    View child = getChildAt(i);
    if (child instanceof BlaBla){
        // Do something wonderful
    }
}

这是非常低效的,因为我在很多地方都有这些实例,特别是在嵌套的地方,所以我需要递归这个方法。

我的第二个选项

使用动态代码或ID并使用findViewByIdfindViewWithTag。但问题是,它使配置更多,并且一如既往地使软件更复杂。

  

所以我的问题是:如何在视图树中进行完整的搜索   为了在不进行搜索的情况下查找组件的所有实例   我自己(因为它可能效率很低)?就是它   不知怎的可能?

1 个答案:

答案 0 :(得分:1)

因此,我不确定第二个选项是否可行,因为在这种情况下,您需要在运行时创建此视图,并为某些生成的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这样的东西。