Android-将视图动态添加到视图


148

我有一个视图布局-

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="0px"
    android:orientation="vertical">

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/items_header"
        style="@style/Home.ListHeader" />

    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/items_none"
        android:visibility="gone"
        style="@style/TextBlock"
        android:paddingLeft="6px" />

    <ListView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/items_list" />


</LinearLayout>

我想做的是在我的主要活动中使用这样的布局

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="0px"
    android:id="@+id/item_wrapper">
</LinearLayout>

我想遍历数据模型,并将由第一个布局组成的多个视图注入到主布局中。我知道我可以通过完全在代码内构建控件来做到这一点,但是我想知道是否存在一种动态构建视图的方法,以便我可以继续使用布局而不是将所有内容都放入代码中。


Answers:


230

使用,LayoutInflater根据您的布局模板创建一个视图,然后将其注入到您需要的视图中。

LayoutInflater vi = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.your_layout, null);

// fill in any details dynamically here
TextView textView = (TextView) v.findViewById(R.id.a_text_view);
textView.setText("your text");

// insert into main view
ViewGroup insertPoint = (ViewGroup) findViewById(R.id.insert_point);
insertPoint.addView(v, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

您可能需要调整要在其中插入视图的索引。

此外,根据您希望其适合父视图的方式设置LayoutParams。例如,使用FILL_PARENT,或MATCH_PARENT等等。


2
这是您要在主视图中放置动态生成的布局的地方。那就是您必须从自己的代码中填写的内容。
Mark Fisher

对于那些现在想尝试一下的人-如第一行所示获得的布局充气机仍然可以解决,但似乎不起作用,而是使用getLayoutInflater()
Brendan

2
LayoutInflater vi = getLayoutInflater();从活动中使用以保留活动主题,否则您将无法获得。
akarthik10 '16

1
@MrG您应该对SO提出一个单独的问题。这个问题是关于如何动态创建视图的,而不是关于片段的。
马克·费舍尔

2
@Arsh如果您有一个新问题和特定问题,请提出一个单独的SO问题,详细说明您尝试过的哪些代码不起作用,请在此处进行注释。
Mark Fisher

36

LayoutInflater上课。

LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup parent = (ViewGroup)findViewById(R.id.where_you_want_to_insert);
inflater.inflate(R.layout.the_child_view, parent);

如何将onClicklistener添加到已膨胀的个人视图。请提供
摘要


14

为了使@Mark Fisher的答案更加清晰,被插入的视图应为Layout文件夹下的xml文件,但其中不应包含LinearLineLayout等布局(ViewGroup)。我的例子:

RES /布局/my_view.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/i_am_id"
    android:text="my name"
    android:textSize="17sp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1"/>

然后,插入点应为LinearLayout之类的布局:

RES /布局/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/aaa"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/insert_point"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </LinearLayout>

</RelativeLayout>

然后代码应该是

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_shopping_cart);

    LayoutInflater inflater = getLayoutInflater();
    View view = inflater.inflate(R.layout.my_view, null);
    ViewGroup main = (ViewGroup) findViewById(R.id.insert_point);
    main.addView(view, 0);
}

我发布这个非常相似的答案的原因是,当我尝试实现Mark的解决方案时,我陷入了应该为insert_point和子视图使用哪个xml文件的问题。首先,我在子视图中使用了布局,但完全没有用,这花了我几个小时才能弄清楚。所以希望我的探索可以节省别人的时间。


如果我们使用for循环添加多个视图,那么@York Yang如何在此处添加竞争ID。
拉胡尔·库什瓦哈

5
// Parent layout
LinearLayout parentLayout = (LinearLayout)findViewById(R.id.layout);

// Layout inflater
LayoutInflater layoutInflater = getLayoutInflater();
View view;

for (int i = 1; i < 101; i++){
    // Add the text layout to the parent layout
    view = layoutInflater.inflate(R.layout.text_layout, parentLayout, false);

    // In order to get the view we have to use the new view with text_layout in it
    TextView textView = (TextView)view.findViewById(R.id.text);
    textView.setText("Row " + i);

    // Add the text view to the parent layout
    parentLayout.addView(textView);
}

1
尽管此代码段可能是解决方案,但包括说明确实有助于提高您的帖子质量。请记住,您将来会为读者回答这个问题,而这些人可能不知道您提出代码建议的原因。
yivi

我如何获得使用For Loop创建的不同视图的ID。
拉胡尔·库什瓦哈
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.