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>

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


回答:


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
動的に生成されたレイアウトをメインビューに配置する場所です。それはあなたがあなた自身のコードから記入しなければならないビットです。
マークフィッシャー

今すぐ試してみたい人のために-最初の行に示されているように取得されたレイアウトインフレーターは解決しますが機能しないようです。代わりに使用してくださいgetLayoutInflater()
ブレンダン

2
LayoutInflater vi = getLayoutInflater();アクティビティから使用して、他では得られないアクティビティテーマを保存します。
akarthik10

1
@MrG SOについて別の質問をする必要があります。この質問は、フラグメントではなく、ビューを動的に作成する方法についてです。
マークフィッシャー

2
@Arsh新しい質問や特定の問題がある場合は、ここでコメントするのではなく、試行したどのコードが機能しないのかを詳しく説明する別のSO質問を投げかけます。
マークフィッシャー

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を追加する方法。スニペットを提供してください
Sagar Devanga '28

20

カスタムアダプターを備えたListViewで、指定されたレイアウトを拡張するために本当に必要なもののように見えます。ArrayAdapterとメソッドnotifyDataSetChanged()を使用すると、ビューの生成とレンダリングを完全に制御できます。

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


14

@Markフィッシャーの回答をより明確にするために、インフレートされる挿入されたビューは、レイアウトフォルダーの下の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);
}

この非常によく似た回答を投稿する理由は、マークのソリューションを実装しようとしたときに、insert_pointと子ビューにどのxmlファイルを使用すればよいかわからなくなったためです。私は最初に子ビューでレイアウトを使用しましたが、それは完全に機能していなかったため、理解するのに数時間かかりました。ですから、私の探求が他の人の時間を節約できることを願っています。


@York Yangは、forループを使用して複数のビューを追加する場合、どのようにしてIdのviesをここに追加できますか。
Rahul Kushwaha

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

Forループを使用して作成されたさまざまなビューのIDを取得するにはどうすればよいですか。
Rahul Kushwaha
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.