Android - Aggiungi dinamicamente viste alla vista


148

Ho un layout per una vista -

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

Quello che voglio fare è nella mia attività principale con un layout come questo

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

Voglio scorrere il mio modello di dati e iniettare più viste costituite dal primo layout nel layout principale. So che posso farlo costruendo i controlli completamente all'interno del codice, ma mi chiedevo se ci fosse un modo per costruire dinamicamente le viste in modo da poter continuare a usare un layout invece di mettere tutto nel codice.


Puoi controllare la risposta per questo stackoverflow.com/questions/3995215/…
Dimmi come

Risposte:


230

Utilizzare LayoutInflaterper creare una vista in base al modello di layout, quindi iniettarla nella vista in cui è necessaria.

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

Potrebbe essere necessario regolare l'indice nel punto in cui si desidera inserire la vista.

Inoltre, imposta LayoutParams in base al modo in cui desideri che si adatti alla vista padre. ad es. con FILL_PARENT, o MATCH_PARENT, ecc.


2
è dove mai vuoi mettere il layout generato dinamicamente nella vista principale. questo è il bit che devi compilare dal tuo codice.
Mark Fisher,

Per coloro che vogliono provarlo ora - il gonfiatore di layout ottenuto come mostrato nella prima riga si risolve ancora ma non sembra funzionare, invece usagetLayoutInflater()
Brendan

2
Utilizzare LayoutInflater vi = getLayoutInflater();da un'attività per preservare il tema dell'attività che non si ottiene diversamente.
Akarthik10,

1
@MrG Dovresti porre una domanda separata su SO. Questa domanda riguarda come creare dinamicamente le viste, non sui frammenti.
Mark Fisher,

2
@Arsh Se hai una nuova domanda e un problema specifico, solleva una domanda SO separata che descriva in dettaglio quale codice hai provato che non funziona invece di commentare qui.
Mark Fisher

36

Vedi la LayoutInflaterlezione.

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

come aggiungo onClicklistener alle visualizzazioni individuali che sono state gonfiate. Fornisci uno snippet
Sagar Devanga,


14

Per rendere più chiara la risposta di @Mark Fisher, la vista inserita da gonfiare dovrebbe essere un file xml nella cartella layout ma senza un layout (ViewGroup) come LinearLayout ecc. All'interno. Il mio esempio:

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

Quindi, il punto di inserimento dovrebbe essere un layout come 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>

Quindi il codice dovrebbe essere

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

Il motivo per cui invio questa risposta molto simile è che quando ho cercato di implementare la soluzione di Mark, mi sono bloccato su quale file xml dovrei usare per insert_point e la vista figlio. Ho usato il layout nella vista bambino in primo luogo e non funzionava assolutamente, il che mi ha impiegato diverse ore per capire. Quindi spero che la mia esplorazione possa far risparmiare tempo agli altri.


@York Yang come posso aggiungere Id's of vies qui se aggiungiamo più di una vista usando for loop.
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
Sebbene questo frammento di codice possa essere la soluzione, includere una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro e che queste persone potrebbero non conoscere i motivi del tuo suggerimento sul codice.
yivi,

Come posso ottenere ID di diverse viste create usando For Loop.
Rahul Kushwaha,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.