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

Posted

技术标签:

【中文标题】检查视图元素是不是以编程方式添加到布局中【英文标题】:Check if view element is added to layout or not programmatically检查视图元素是否以编程方式添加到布局中 【发布时间】:2013-07-17 07:36:02 【问题描述】:

在我的片段类中,我有条件地以编程方式将子视图元素添加到我的布局中:

LinearLayout child = (LinearLayout) inflater.inflate(R.layout.child_view, null);

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

container.addView(child, params);

由于上述代码将有条件地运行,所以,在某些时候,我想检查是否添加了子视图,如何以编程方式进行检查?

【问题讨论】:

添加一个标志变量,表示视图已添加。 【参考方案1】:

如果你通过inflater创建视图,你可以检查他的父母

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

【讨论】:

也许public boolean hasParent(View view) return (view != null && view.getParent() != null); 然后他/她可以打电话给if(hasParent(child))...; 稍后检查。 (编辑评论以处理愚蠢的格式错误)【参考方案2】:

我认为你可以简单地使用

findViewById(your_view_id) 

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

【讨论】:

这是一个非常繁重的计算,因为它必须遍历视图组下视图的层次结构,这可能是大量的视图。另一个答案 .getParent() 是字段查找 您是说谷歌工程师在制作 andorid sdk 的方式是在每个活动开始时每个应用程序都会为布局中的每个视图执行一次非常繁重的计算?我不这么认为 嗯,这就是为什么在使用 ListView 或 RecyclerView 时存在ViewHolder 模式的原因,因为如果层次结构没有改变,我们不希望每次都通过层次结构。就像我说的,所花费的时间取决于你的层次结构的深度。但是,和往常一样,如果你不相信我,你可以去source。 看,我不是说 findViewById 是一个轻量级的操作,但实际上视图持有者模式是用来防止对每一行的布局进行膨胀,这是一个较重的操作。如果您只调用一次 findViewById,即使您知道速度较慢的设备也不会因此受到影响 您是否阅读了我在评论中添加的链接?第一段是这样说的:“你的代码可能会在 ListView 的滚动过程中频繁调用 findViewById(),这会降低性能。即使 Adapter 返回一个膨胀的视图进行回收,你仍然需要查找元素和更新它们。避免重复使用 findViewById() 的一种方法是使用“视图持有者”设计模式。”【参考方案3】:

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

在添加视图之前和之后使用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();

【讨论】:

【参考方案4】:

或者,如果您要查找 view 实例,您可以:

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

【讨论】:

【参考方案5】:

我不能写评论,所以我把它写在这里作为解决方案: 从 API 级别 19 开始,您可以调用 isAttachedToWindow(),这并没有多大帮助,但如果您的目标是 API 19 或更高,那么这应该可以通过文档来实现。

【讨论】:

【参考方案6】:

通过androidX,您可以使用ViewGroup.contains(view: View): Boolean 扩展功能。

【讨论】:

【参考方案7】:

也许你可以试试这个

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) 

        
    );

【讨论】:

以上是关于检查视图元素是不是以编程方式添加到布局中的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式将自动布局添加到肋骨中添加的现有自动布局视图

使用布局约束以编程方式将视图添加到滚动视图

以编程方式发送到从界面生成器创建的前/后元素

自动布局 - 以编程方式垂直排列元素,中间有空格?

以编程方式将片段添加到android中的框架布局

将视图添加到底部的垂直线性布局(以编程方式)