检查视图元素是否以编程方式添加到布局中

35
在我的片段类中,我有条件地通过编程向我的布局动态添加了一个子视图元素:
LinearLayout child = (LinearLayout) inflater.inflate(R.layout.child_view, null);

LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,100);

container.addView(child, params);

由于上面的代码将会有条件地运行,因此在某个时候,我想要检查子视图是否已经添加,如何通过编程来进行这种检查?


添加一个标志变量,表示视图已被添加。 - RCB
7个回答

52

如果您通过 inflater 创建视图,您可以检查其父级

if(view.getParent() != null) {...}

也许可以这样写一个程序:public boolean hasParent(View view){ return (view != null && view.getParent() != null); } 然后在需要检查的时候,他/她可以调用 if(hasParent(child)){...}; - Benjamin Kershner

29
我认为你可以简单地使用

findViewById(your_view_id) 

方法:如果其结果为null,则视图不存在,否则视图存在。


4
这是一个非常繁重的计算,因为它必须遍历视图组下面的视图层次结构,这可能有大量视图。另一个答案中的.getParent()是一个字段查找。 - Jorge Aguilar
你是在说谷歌的工程师们以一种方式制作了安卓SDK,使得每个活动的开始,每个应用程序都会为布局中的每个视图进行一次非常繁重的计算吗?我不这么认为。 - Apperside
1
这就是为什么在使用ListView或RecyclerView时存在ViewHolder模式,因为我们不想每次都遍历层次结构,如果层次结构没有改变。就像我说的,所需的时间取决于您的层次结构深度。但是,像往常一样,如果您不相信我,可以去源代码查看。 - Jorge Aguilar
看,我并不是说findViewById是一个轻量级操作,但实际上视图持有者模式被用来防止为每一行充气布局,这是远比较重的操作。如果你只调用一次findViewById,即使是速度较慢的设备也不会受到影响。 - Apperside
3
你读了我评论中添加的链接吗?第一段说:“你的代码在滚动ListView时可能会频繁调用findViewById(),这会降低性能。即使适配器为回收而返回已充气的视图,你仍然需要查找元素并更新它们。避免重复使用findViewById()的方法是使用“视图持有者”设计模式。” - Jorge Aguilar

25

抱歉回复晚了,但您可以尝试这个替代方案:

在添加视图之前和之后使用 container.getChildCount();。例如:

int x = container.getChildCount();

container.addView(child, params);

int y = container.getChildCount();

if(y > x)
   Toast.makeText(context, "View Successfully Added!", Toas.LENGTH_SHORT).show();

16

或者如果你有要找的 view 实例,可以:

if (container.indexOfChild(childView) == -1) {
  // Add child to container.
}

8

使用 AndroidX ,您可以使用 ViewGroup.contains(view: View): Boolean 扩展函数。


6

我无法写评论,所以我在这里写成解决方案:

从API 19级开始,您可以调用isAttachedToWindow()方法,虽然不是非常有用,但如果您的目标是API 19或更高版本,则根据文档应该可以使用。


0

也许你可以尝试这个

child.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            child.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            // add to parent
        }
    });

或者这个

child.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
        @Override
        public void onViewAttachedToWindow(View v) {

        }

        @Override
        public void onViewDetachedFromWindow(View v) {

        }
    });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接