2012-04-02 84 views
20

在我的Android动作中,我需要动态地(在运行时)在布局中的特定位置添加一个视图。要添加的视图在运行时确定。例如,可能看起来像这样的布局:动态添加视图的Android布局占位符

<LinearLayout ...> 
    <TextView ... /> 
    <!-- Dynamic item to be added here --> 
    <TextView ... /> 
</LinearLayout> 

实现此目的的最佳方法是什么?

一种解决方案是使用layout.addView(view, index),但我宁愿不要硬编码索引。

另一种解决方案是使用的FrameLayout作为占位符,和地点可以在的FrameLayout内部动态视图,例如:

<LinearLayout ...> 
    <TextView ... /> 
    <FrameLayout android:id="@+id/placeholder" /> 
    <TextView ... /> 
</LinearLayout> 

然后:

findViewById(R.id.placeholder).addView(view); 

然而,这增加了一个不必要的视图在层次结构中。

什么是推荐的方式做到这一点?

回答

13

我觉得用一个FrameLayout里为您的视图的占位符“在运行时添加”是一个很好的解决方案。

我不会担心对性能的额外“unnecesssary”观点的影响。

+1

谢谢。我最终使用'findViewById(R.id.placeholder).addView(view);',其中占位符可以是一个FrameLayout,或者任何其他布局,如果视图只需添加在最后,如ScrollView。 – Ralf 2012-04-02 13:08:43

+0

你可能会得到这样的嵌套的意见,这可能导致在某些情况下stuckoverflowerror,一个深树由于对UI线程 – 2013-09-27 05:22:10

7

您也可以使用ViewStub来实现此“懒惰包含”行为,如Android Developers的此(相当老的)article中所述。

+1

对于有限STACKSIZE“懒包括”你需要指定布局文件在编译时包括,但我需要能够添加一个视图(在运行时确定)。我编辑了这个问题来澄清。 – Ralf 2012-08-14 10:18:35

+1

在ViewStub中指定的布局文件可以是一个空的LinearLayout,RelativeLayout,... WhateverLayout,可以动态地填充任意数量的.AddView()。我不明白为什么这不会像你上面提到的那样工作(我现在正在实现这个) – samosaris 2013-05-22 20:39:39

+2

ViewStub stub =(ViewStub)findViewById(R.id.container_stub); stub.setLayoutResource(R.layout.activity_home); – frostymarvelous 2014-07-03 17:09:15

1

您可以使用addView(查看孩子,INT指数)没有硬编码的具体指标。

如果视图的其中一个邻居可以修复(例如,在要插入项目的位置之前有一个特定标签),则可以获取该视图的索引,然后插入动态视图:

View previousView = findViewById(ID_OF_PREVIOUS_VIEW); 
ViewGroup parent = (ViewGroup)previousView.getParent(); 
int previousIndex = parent.indexOfChild(previousView); 
parent.addView(theDynamicallyCreatedView, previousIndex + 1); 

或者你可以使用一个ViewStub,但不是膨胀的布局,只是将其删除:

View placeholder = findViewById(ID_OF_STUB); 
ViewGroup parent = (ViewGroup)previousView.getParent(); 
int index = parent.indexOfChild (placeholder); 
parent.removeViewAt(index); 
parent.addView(theDynamicallyCreatedView, index); 

这样你就不会与一个巨大的视图层次结束。