Comment ajouter des éléments à une listView dynamiquement dans Android


326

Quelqu'un peut-il expliquer ou suggérer un tutoriel pour créer une listView dans Android?

Voici mes exigences:

  • Je devrais pouvoir ajouter dynamiquement de nouveaux éléments en appuyant sur un bouton.
  • Doit être assez simple à comprendre (éventuellement sans aucune amélioration des performances ou convertview, par exemple)

Je sais qu'il y a pas mal de questions sur ce sujet, publiées ici sur StackOverflow, mais je n'ai trouvé aucune réponse à ma question. Merci!


3
La réponse actuellement la plus votée de Shardul est considérée comme de haute qualité et les utilisateurs ont exprimé leur sentiment qu'elle devrait être acceptée. Pouvez-vous envisager de l'accepter?
Matt Welke

Réponses:


583

Créez d'abord une disposition XML dans le res/layout/main.xmldossier de votre projet :

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

Il s'agit d'une disposition simple avec un bouton en haut et une vue de liste en bas. Notez que le ListViewa l'identifiant @android:id/listqui définit la valeur ListViewpar défaut qu'un ListActivitypeut utiliser.

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 est la disposition des éléments de liste par défaut fournie par Android, et vous pouvez utiliser cette disposition de stock pour les choses non complexes.

listItemsest une liste qui contient les données affichées dans le ListView. Toute l'insertion et le retrait doivent être effectués listItems; les changements dans listItemsdoivent être reflétés dans la vue. Cela est géré par ArrayAdapter<String> adapter, qui doit être notifié en utilisant:

adapter.notifyDataSetChanged();

Un adaptateur est instancié avec 3 paramètres: le contexte, qui pourrait être le vôtre activity/listactivity; la disposition de votre élément de liste individuel; et enfin, la liste, qui est les données réelles à afficher dans la liste.


2
Je ne comprends pas comment le ListView s'attache à notre activité ici.
Breedly

7
@Breedly Parce que c'est une ListActivity et non une Activity qui a une mise en page avec une ListView . Vous n'avez pas besoin de trouver la vue de l'identifiant. Comme vous pouvez le lire sur la référence: ListActivity is an activity that includes a ListView as its only layout element by default. [...] (it) hosts a ListView object. Ainsi, par défaut, les méthodes (comme setAdapter , etc.) sont "à l'intérieur" de la classe.
fllo

Montrons le bonheur quand la bonne réponse est obtenue: /
support_ms

1
Si l'élément dans ArrayList est plus compliqué tel que le chargement à partir d'Internet et que chaque élément contient une image vidéo et quelque chose comme ça, cette approche serait-elle affectée par les performances?
zionpi

1
Comment pourrais-je implémenter cela dans un fragment?
Oamar Kanji

64

au lieu de

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

vous pouvez appeler directement

adapter.add("New Item");

@gumuruh l'adaptateur lui-même est modifiable afin que nous puissions directement ajouter ou supprimer des objets qui appelleront automatiquement notifyDatasetChanged () et getView () de listView. Cela réduit la ligne de code supplémentaire.
venkat530

donc en ajoutant dans l'adaptateur appelez automatiquement notifyDatasetChanged ()? Oh je vois. Merci @ venkat530. Mais qu'en est-il de la liste elle-même? Je veux dire si, disons tout d'abord, il a créé une liste d'arrays qui a servi de conteneur de données pour l'adaptateur. Et maintenant, vous ajoutez simplement un élément directement à l'adaptateur au lieu de la liste d'arrayl. Les données de la liste des arraylistes seraient-elles mises à jour / intactes?
gumuruh

1
@gumuruh le second est la meilleure pratique car il est synchronisé.
Ricardo

1
@gumuruh de l'expérimentation superficielle et du code source d'ArrayAdapter [ github.com/android/platform_frameworks_base/blob/master/core/… , il semble que l'ensemble de données sous-jacent sera également modifié.
CCJ

J'ai réussi à obtenir la réponse de Shardul, puis je l'ai cassée et je n'ai pas pu trouver comment la réparer. Sur un coup de tête, j'ai pensé que j'allais essayer ça, et le tour est joué, ça marche à nouveau! Merci beaucoup! Cependant, je ne sais pas comment ni pourquoi cela a été corrigé. Une idée?
donutguy640

55

Tout d'abord, vous devez ajouter un ListView, un EditText et un bouton dans votre activity_main.xml.

Maintenant, dans votre 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();
        }
    });
}

Cela fonctionne pour moi, j'espère que je vous ai aidé


4
Très bonne explication et merci surtout pour expliquer l'élément adaptateur - qui semble magiquement apparaître dans les exemples de tout le monde. :)
raddevus

1
Ceci est le meilleur exemple que j'ai trouvé pour cela :)
Dinuka Salwathura

Cette réponse satisfait ce que la personne a demandé. Simple et propre sans améliorations compliquées. La première réponse introduit ListActivity, que seuls les grands maîtres connaissent. Mon seul problème est maintenant de savoir comment ajouter des trucs et des trucs aux vues dans la liste. Il me semble que je n'ajoute que des cordes.

Une optimisation peut être de créer un objet List sans nom dans l'adaptateur plutôt que de créer un pointeur 16 bits vers un objet List. Ce qui n'est pas nécessaire après la création de l'adaptateur car l'adaptateur a une méthode d'ajout.

17

Si vous souhaitez avoir le ListView dans une AppCompatActivity au lieu de ListActivity, vous pouvez faire ce qui suit (Modifier la réponse de @ 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;
        }
    }
}

Et dans votre mise en page au lieu d'utiliser, android:id="@android:id/list"vous pouvez utiliserandroid:id="@+id/listDemo"

Alors maintenant, vous pouvez avoir un ListViewintérieur normal AppCompatActivity.


13

Code du fichier 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();
            }
        });
    }
}

Code du fichier de mise en page 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>

Capture d'écran

entrez la description de l'image ici


0

La réponse courte: lorsque vous créez un ListView, vous lui transmettez une référence aux données. Maintenant, chaque fois que ces données seront modifiées, cela affectera la vue de liste et y ajoutera donc l'élément, après avoir appelé adapter.notifyDataSetChanged () ;.

Si vous utilisez un RecyclerView, mettez à jour uniquement le dernier élément (si vous l'avez ajouté à la fin de la liste des objs) pour économiser de la mémoire avec: mAdapter.notifyItemInsert (mItems.size () - 1);


0

Ceci est la réponse simple comment ajouter des données dynamiquement dans 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")

    }
}

Ici, je viens d'expliquer deux façons, nous pouvons le faire de nombreuses façons.


Où est la partie que vous l'ajoutez à la ListView?
Onie Maniego

@OnieManiego ici, j'ai ajouté les éléments à listview de deux manières, vous pouvez voir qu'au dessus 1. listItems.add ("a") listItems.add ("b") listItems.add ("c") listItems.add ("d ") listItems.add (" e ") c'est la première façon que j'ajoute 2. pour (items dans le tableau) listItems.add (items) la deuxième façon j'ai ajouté tous les articles du tableau
sirajudheen tk

@OnieManiego j'espère que vous comprenez, si cela vous est utile pls upvote
sirajudheen tk
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.