web-dev-qa-db-ja.com

Android - ビューに動的にビューを追加する

ビュー用のレイアウトがあります -

<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>

データモデルをループ処理して、最初のレイアウトからなる複数のビューをメインレイアウトに挿入します。コード内でコントロールを完全に構築することでこれを実現できることはわかっていますが、コードをすべて配置する代わりにレイアウトを使用し続けることができるようにビューを動的に構築する方法があるかどうか疑問に思いました。

138
Josh

レイアウトテンプレートに基づいてビューを作成するには、 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_PARENTMATCH_PARENTなどで.

214
Mark Fisher

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);
34
Gabriel Negut

それはあなたが本当に指定されたレイアウトを膨らませるためにカスタムアダプタを持ったリストビューに欲しいもののように見えます。 ArrayAdapter とメソッドnotifyDataSetChanged()を使うことで、ビューの生成とレンダリングを完全に制御できます。

これらのチュートリアルを見てください。

19
Aleadam

@Mark Fisherの回答をより明確にするために、膨張させる挿入ビューはレイアウトフォルダーの下にあるxmlファイルである必要がありますが、その中にはLinearLayoutなどのレイアウト(ViewGroup)はありません。私の例:

res/layout/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/layout/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ファイルを使用すればよいかということに固執したためです。私は最初に子ビューでレイアウトを使用しましたが、それはまったく機能していなかったので、把握するのに数時間かかりました。だから私の探査が他の人の時間を節約できることを願っています。

9
York Yang
// 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
Tienanhvn