Come aggiungere elementi a un elencoVisualizza dinamicamente in Android


326

Qualcuno può spiegare o suggerire un tutorial per creare un listView in Android?

Ecco i miei requisiti:

  • Dovrei essere in grado di aggiungere dinamicamente nuovi elementi premendo un pulsante.
  • Dovrebbe essere abbastanza semplice da capire (possibilmente senza alcun miglioramento delle prestazioni o convertview, per esempio)

So che ci sono alcune domande su questo argomento, pubblicate qui su StackOverflow, ma non sono riuscito a trovare nessuna risposta alla mia domanda. Grazie!


3
La risposta attualmente più votata da Shardul è considerata di alta qualità e gli utenti hanno espresso la sensazione che debba essere accettata. Puoi prendere in considerazione l'idea di accettarlo?
Matt Welke,

Risposte:


583

Crea prima un layout XML nella res/layout/main.xmlcartella del tuo progetto :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <Button
        android:id="@+id/addBtn"
        android:text="Add New Item"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:onClick="addItems"/>
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:drawSelectorOnTop="false"
    />
</LinearLayout>

Questo è un layout semplice con un pulsante in alto e una vista elenco in basso. Si noti che l' ListViewha l'ID @android:id/listche definisce il default ListViewdi un ListActivitypossibile utilizzare.

public class ListViewDemo extends ListActivity {
    //LIST OF ARRAY STRINGS WHICH WILL SERVE AS LIST ITEMS
    ArrayList<String> listItems=new ArrayList<String>();

    //DEFINING A STRING ADAPTER WHICH WILL HANDLE THE DATA OF THE LISTVIEW
    ArrayAdapter<String> adapter;

    //RECORDING HOW MANY TIMES THE BUTTON HAS BEEN CLICKED
    int clickCounter=0;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);
        adapter=new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1,
            listItems);
        setListAdapter(adapter);
    }

    //METHOD WHICH WILL HANDLE DYNAMIC INSERTION
    public void addItems(View v) {
        listItems.add("Clicked : "+clickCounter++);
        adapter.notifyDataSetChanged();
    }
}

android.R.layout.simple_list_item_1 è il layout predefinito dell'elemento dell'elenco fornito da Android ed è possibile utilizzare questo layout di scorta per cose non complesse.

listItemsè un elenco che contiene i dati mostrati in ListView. Tutto l'inserimento e la rimozione devono essere eseguiti listItems; le modifiche listItemsdovrebbero riflettersi nella vista. Questo è gestito da ArrayAdapter<String> adapter, che dovrebbe essere notificato usando:

adapter.notifyDataSetChanged();

Un adattatore viene istanziato con 3 parametri: il contesto, che potrebbe essere tuo activity/listactivity; il layout della singola voce dell'elenco; e, infine, l'elenco, ovvero i dati effettivi da visualizzare nell'elenco.


2
Non capisco come ListView si leghi alla nostra attività qui.
Breedly,

7
@Breedly Perché è un ListActivity e non un'attività che ha un layout con un ListView . Non è necessario trovare la vista dell'ID. Come si può leggere sul riferimento: ListActivity is an activity that includes a ListView as its only layout element by default. [...] (it) hosts a ListView object. Quindi, per impostazione predefinita, i metodi (come setAdapter , ecc.) Sono "all'interno" della classe.
fllo

Mostriamo felicità quando si ottiene la risposta giusta: /
support_ms

1
Se l'elemento in ArrayList è più complicato, come il caricamento da Internet e ogni elemento contiene video di immagini e qualcosa del genere, questo approccio affronterebbe le prestazioni?
zionpi,

1
Come potrei implementarlo in un frammento?
Oamar Kanji,

64

invece di

listItems.add("New Item");
adapter.notifyDataSetChanged();

puoi chiamare direttamente

adapter.add("New Item");

@gumuruh l'adattatore stesso è mutabile in modo da poter aggiungere o rimuovere direttamente gli oggetti che chiameranno automaticamente notificationDatasetChanged () e getView () di listView. Ciò riduce la riga aggiuntiva di codice.
venkat530,

quindi aggiungendo nell'adattatore chiamare automaticamente notificationDatasetChanged ()? Oh, capisco. Grazie @ venkat530. E la lista stessa? Voglio dire, per prima cosa, ha creato un arraylist che ha usato come contenitore di dati per l'adattatore. E ora aggiungi semplicemente un elemento direttamente all'adattatore anziché all'arraylist. I dati dell'arraylist verrebbero aggiornati / non toccati?
Gumuruh,

1
@gumuruh la seconda è la migliore pratica perché è sincronizzata.
Ricardo,

1
@gumuruh dalla sperimentazione superficiale e il codice sorgente di ArrayAdapter [ github.com/android/platform_frameworks_base/blob/master/core/… , sembra che anche il set di dati sottostante verrà modificato.
CCJ

Ho fatto funzionare la risposta di Shardul, poi l'ho rotta e non sono riuscita a capire come ripararla. Per un capriccio, ho pensato di provare questo, e voilà, funziona di nuovo! Grazie mille! Tuttavia, non ho idea di come o perché lo abbia risolto. Qualche idea?
donutguy640,

55

Innanzitutto, devi aggiungere un ListView, un EditText e un pulsante in activity_main.xml.

Ora, nel tuo ActivityMain:

private EditText editTxt;
private Button btn;
private ListView list;
private ArrayAdapter<String> adapter;
private ArrayList<String> arrayList;

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

    editTxt = (EditText) findViewById(R.id.editText);
    btn = (Button) findViewById(R.id.button);
    list = (ListView) findViewById(R.id.listView);
    arrayList = new ArrayList<String>();

    // Adapter: You need three parameters 'the context, id of the layout (it will be where the data is shown),
    // and the array that contains the data
    adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, arrayList);

    // Here, you set the data in your ListView
    list.setAdapter(adapter);

    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            // this line adds the data of your EditText and puts in your array
            arrayList.add(editTxt.getText().toString());
            // next thing you have to do is check if your adapter has changed
            adapter.notifyDataSetChanged();
        }
    });
}

Questo funziona per me, spero di averti aiutato


4
Ottima spiegazione e grazie soprattutto per aver spiegato l'elemento adattatore - che sembra apparire magicamente negli esempi di tutti gli altri. :)
Raddevus,

1
Questo è il miglior esempio che ho trovato per questo :)
Dinuka Salwathura,

Questa risposta ha soddisfatto ciò che la persona ha chiesto. Semplice e pulito senza complicati miglioramenti. La risposta migliore in realtà introduce ListActivity, che solo i grandi maestri conoscono. Il mio unico problema ora è come aggiungere disegnabili e cose alle viste nell'elenco. Mi sembra che sto solo aggiungendo delle stringhe.

Un'ottimizzazione potrebbe essere quella di creare un oggetto List senza nome nell'adapter piuttosto che creare un puntatore a 16 bit a un oggetto list. Che non è necessario dopo aver creato l'adattatore perché l'adattatore ha un metodo add.

17

Se vuoi avere ListView in un AppCompatActivity invece di ListActivity, puoi fare quanto segue (Modifica della risposta di Shardul):

public class ListViewDemoActivity extends AppCompatActivity {
    //LIST OF ARRAY STRINGS WHICH WILL SERVE AS LIST ITEMS
    ArrayList<String> listItems=new ArrayList<String>();

    //DEFINING A STRING ADAPTER WHICH WILL HANDLE THE DATA OF THE LISTVIEW
    ArrayAdapter<String> adapter;

    //RECORDING HOW MANY TIMES THE BUTTON HAS BEEN CLICKED
    int clickCounter=0;
    private ListView mListView;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.activity_list_view_demo);

        if (mListView == null) {
            mListView = (ListView) findViewById(R.id.listDemo);
        }

        adapter=new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1,
                listItems);
        setListAdapter(adapter);
    }

    //METHOD WHICH WILL HANDLE DYNAMIC INSERTION
    public void addItems(View v) {
        listItems.add("Clicked : "+clickCounter++);
        adapter.notifyDataSetChanged();
    }

    protected ListView getListView() {
        if (mListView == null) {
            mListView = (ListView) findViewById(R.id.listDemo);
        }
        return mListView;
    }

    protected void setListAdapter(ListAdapter adapter) {
        getListView().setAdapter(adapter);
    }

    protected ListAdapter getListAdapter() {
        ListAdapter adapter = getListView().getAdapter();
        if (adapter instanceof HeaderViewListAdapter) {
            return ((HeaderViewListAdapter)adapter).getWrappedAdapter();
        } else {
            return adapter;
        }
    }
}

E nel tuo layout invece di usare android:id="@android:id/list"puoi usareandroid:id="@+id/listDemo"

Quindi ora puoi avere un ListViewinterno normale AppCompatActivity.


13

Codice per il file MainActivity.java.

public class MainActivity extends Activity {

    ListView listview;
    Button Addbutton;
    EditText GetValue;
    String[] ListElements = new String[] {
        "Android",
        "PHP"
    };

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

        listview = (ListView) findViewById(R.id.listView1);
        Addbutton = (Button) findViewById(R.id.button1);
        GetValue = (EditText) findViewById(R.id.editText1);

        final List < String > ListElementsArrayList = new ArrayList < String >
            (Arrays.asList(ListElements));


        final ArrayAdapter < String > adapter = new ArrayAdapter < String >
            (MainActivity.this, android.R.layout.simple_list_item_1,
                ListElementsArrayList);

        listview.setAdapter(adapter);

        Addbutton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                ListElementsArrayList.add(GetValue.getText().toString());
                adapter.notifyDataSetChanged();
            }
        });
    }
}

Codice per il file di layout activity_main.xml.

<RelativeLayout 
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context="com.listviewaddelementsdynamically_android_examples
    .com.MainActivity" >

  <Button
    android:id="@+id/button1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/editText1"
    android:layout_centerHorizontal="true"
    android:text="ADD Values to listview" />

  <EditText
    android:id="@+id/editText1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="26dp"
    android:ems="10"
    android:hint="Add elements listView" />

  <ListView
    android:id="@+id/listView1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/button1"
    android:layout_centerHorizontal="true" >
  </ListView>

</RelativeLayout>

Immagine dello schermo

inserisci qui la descrizione dell'immagine


0

La risposta breve: quando si crea un ListView, gli si passa un riferimento ai dati. Ora, ogni volta che questi dati verranno modificati, influenzerà la visualizzazione elenco e quindi aggiungerà l'elemento ad esso, dopo aver chiamato adapter.notifyDataSetChanged () ;.

Se stai usando un RecyclerView, aggiorna solo l'ultimo elemento (se l'hai aggiunto alla fine dell'elenco degli objs) per risparmiare memoria con: mAdapter.notifyItemInserted (mItems.size () - 1);


0

Questa è la semplice risposta su come aggiungere dati dinamicamente in listview android kotlin

class MainActivity : AppCompatActivity(){

    var listItems = arrayListOf<String>()
    val array = arrayOf("a","b","c","d","e")
    var listView: ListView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.scrollview_layout)

        listItems.add("a")
        listItems.add("b")
        listItems.add("c")
        listItems.add("d")
        listItems.add("e")

        //if you want to add array items to a list you can try this for each loop
        for(items in array)
            listItems.add(items)
        Log.e("TAG","listItems array: $listItems")

    }
}

Qui ho appena spiegato due modi, possiamo farlo in molti modi.


Dov'è la parte che lo aggiungi a ListView?
Onie Maniego,

@OnieManiego qui ho aggiunto gli elementi a listview in due modi, puoi vedere sopra 1. listItems.add ("a") listItems.add ("b") listItems.add ("c") listItems.add ("d ") listItems.add (" e ") questo è il primo modo in cui ho aggiunto 2. per (items in array) listItems.add (items) secondo modo in cui ho aggiunto tutti gli elementi da array
sirajudheen tk

@OnieManiego spero che tu capisca, se questo ti è stato utile, per favore
sirajudheen tk
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.