Android - Ansichten dynamisch zur Ansicht hinzufügen


148

Ich habe ein Layout für eine Ansicht -

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

Was ich tun möchte, ist in meiner Haupttätigkeit mit einem Layout wie diesem

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

Ich möchte mein Datenmodell durchlaufen und mehrere Ansichten, die aus dem ersten Layout bestehen, in das Hauptlayout einfügen. Ich weiß, dass ich dies tun kann, indem ich die Steuerelemente vollständig im Code erstelle, aber ich habe mich gefragt, ob es eine Möglichkeit gibt, die Ansichten dynamisch zu erstellen, damit ich weiterhin ein Layout verwenden kann, anstatt alles in Code einzufügen.


Antworten:


229

Verwenden Sie die Option LayoutInflater, um eine Ansicht basierend auf Ihrer Layoutvorlage zu erstellen, und fügen Sie sie dann in die Ansicht ein, in der Sie sie benötigen.

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

Möglicherweise müssen Sie den Index anpassen, in den Sie die Ansicht einfügen möchten.

Stellen Sie außerdem die LayoutParams so ein, wie sie in die übergeordnete Ansicht passen sollen. zB mit FILL_PARENToder MATCH_PARENTusw.


2
Hier können Sie das dynamisch generierte Layout jederzeit in Ihre Hauptansicht einfügen. Das ist das Bit, das Sie aus Ihrem eigenen Code ausfüllen müssen.
Mark Fisher

Für diejenigen, die dies jetzt ausprobieren möchten - der in der ersten Zeile gezeigte Layout-Inflator wird immer noch aufgelöst, scheint aber nicht zu funktionieren. Verwenden Sie stattdessengetLayoutInflater()
Brendan

2
Verwenden LayoutInflater vi = getLayoutInflater();Sie diese Option aus einer Aktivität, um das Aktivitätsthema beizubehalten, das Sie sonst nicht erhalten.
Akarthik10

1
@ MrG Sie sollten eine separate Frage zu SO stellen. Bei dieser Frage geht es darum, wie Ansichten dynamisch erstellt werden, nicht um Fragmente.
Mark Fisher

2
@Arsh Wenn Sie eine neue Frage und ein bestimmtes Problem haben, stellen Sie eine separate SO-Frage, in der angegeben ist, welcher Code, den Sie ausprobiert haben, nicht funktioniert, anstatt hier zu kommentieren.
Mark Fisher

36

Siehe die LayoutInflaterKlasse.

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

Wie füge ich onClicklistener zu den Ansichten der einzelnen Personen hinzu, die aufgeblasen wurden
? Bitte

20

Es sieht so aus, als ob Sie wirklich eine ListView mit einem benutzerdefinierten Adapter benötigen, um das angegebene Layout aufzublasen. Mit einem ArrayAdapter und der Methode haben notifyDataSetChanged()Sie die volle Kontrolle über die Generierung und das Rendern von Ansichten.

Schauen Sie sich diese Tutorials an


14

Um die Antwort von @Mark Fisher klarer zu machen, sollte die eingeblasene Ansicht, die aufgeblasen wird, eine XML-Datei unter dem Layoutordner sein, jedoch ohne ein Layout (ViewGroup) wie LinearLayout usw. im Inneren. Mein Beispiel:

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

Dann sollte die Einfügemarke ein Layout wie LinearLayout sein:

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>

Dann sollte der Code sein

@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);
}

Der Grund, warum ich diese sehr ähnliche Antwort poste, ist, dass ich beim Versuch, Marks Lösung zu implementieren, nicht sicher war, welche XML-Datei ich für insert_point und die untergeordnete Ansicht verwenden soll. Ich habe zuerst das Layout in der untergeordneten Ansicht verwendet und es hat überhaupt nicht funktioniert, was mich mehrere Stunden gekostet hat, um es herauszufinden. Ich hoffe, meine Erkundung kann anderen Zeit sparen.


@ York Yang, wie kann ich IDs von Vies hier hinzufügen lassen, wenn wir mehr als eine Ansicht mit for-Schleife hinzufügen.
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
Während dieses Code-Snippet die Lösung sein kann, hilft das Hinzufügen einer Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen.
Yivi

Wie kann ich IDs verschiedener Ansichten abrufen, die mit For Loop erstellt wurden?
Rahul Kushwaha
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.