11

J'utilise un ArrayAdapter pour ajouter des éléments à un ListView personnalisé et afficher les résultats dans mon application Android. Le problème que j'ai est que le ArrayAdapter semble attendre jusqu'à ce que tous les éléments soient dedans avant qu'il montre la vue. C'est-à-dire, lorsque j'ajoute les éléments à ArrayAdapter et j'appelle notifyDataSetChanged, il ne met pas à jour le ListView pour montrer l'élément ajouté. Il attend jusqu'à ce que tous les éléments sont ajoutés et GetView est appelé avant d'afficher les éléments.Android - Ajouter et afficher des éléments à ListView un à la fois en utilisant un ArrayAdapter

Ce que je voudrais faire est de montrer l'article immédiatement après l'avoir ajouté à ListView. Est-ce possible?

je crois que le code correspondant est le suivant:

r_adapter = new ReminderAdapater(Activity_ContentSearch.this, R.layout.search_listitem, myList); 
listView.setAdapter(r_adapter); 
... 
r_adapter.notifyDataSetChanged(); 
r_adapter.clear(); 
for(int i = 0; i < myList.size(); i++) 
{ 
    r_adapter.add(myList.get(i)); 
    r_adapter.notifyDataSetChanged(); 
} 

Comme vous pouvez le voir, même si je fais appel notifyDataSetChanged après la méthode d'ajout, il ne met pas à jour en fait le point de vue. Après avoir terminé la boucle ci-dessus, la vue est finalement mise à jour (d'après ce que je sais, c'est parce que GetView n'est pas appelé avant que cette section du code soit terminée).

J'ai essayé de surcharger la méthode add de mon ArrayAdapter personnalisé sans succès, car je n'ai pas accès à la vue dans cette méthode.

Toute aide serait la bienvenue :)

Bara

Répondre

23

UI Android est mono-thread. Vous ne redonnez pas le contrôle à Android à partir du thread d'application principal chaque fois que vous ajoutez une entrée à l'adaptateur. Par conséquent, Android n'a pas la possibilité d'afficher vos entrées tant que vous ne retournez pas le contrôle, et vous ne le faites pas tant que vous n'avez pas rempli votre adaptateur dans son intégralité.

Here is an example montrant l'utilisation d'un AsyncTask pour remplir un ArrayAdapter progressivement via un fil d'arrière-plan.

/*** 
    Copyright (c) 2008-2012 CommonsWare, LLC 
    Licensed under the Apache License, Version 2.0 (the "License"); you may not 
    use this file except in compliance with the License. You may obtain a copy 
    of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required 
    by applicable law or agreed to in writing, software distributed under the 
    License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
    OF ANY KIND, either express or implied. See the License for the specific 
    language governing permissions and limitations under the License. 

    From _The Busy Coder's Guide to Android Development_ 
    http://commonsware.com/Android 
*/ 

package com.commonsware.android.async; 

import android.app.ListActivity; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.SystemClock; 
import android.widget.ArrayAdapter; 
import android.widget.Toast; 
import java.util.ArrayList; 

public class AsyncDemo extends ListActivity { 
    private static final String[] items={"lorem", "ipsum", "dolor", 
             "sit", "amet", "consectetuer", 
             "adipiscing", "elit", "morbi", 
             "vel", "ligula", "vitae", 
             "arcu", "aliquet", "mollis", 
             "etiam", "vel", "erat", 
             "placerat", "ante", 
             "porttitor", "sodales", 
             "pellentesque", "augue", 
             "purus"}; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    setListAdapter(new ArrayAdapter<String>(this, 
         android.R.layout.simple_list_item_1, 
         new ArrayList<String>())); 

    new AddStringTask().execute(); 
    } 

    class AddStringTask extends AsyncTask<Void, String, Void> { 
    @Override 
    protected Void doInBackground(Void... unused) { 
     for (String item : items) { 
     publishProgress(item); 
     SystemClock.sleep(200); 
     } 

     return(null); 
    } 

    @SuppressWarnings("unchecked") 
    @Override 
    protected void onProgressUpdate(String... item) { 
     ((ArrayAdapter<String>)getListAdapter()).add(item[0]); 
    } 

    @Override 
    protected void onPostExecute(Void unused) { 
     Toast 
     .makeText(AsyncDemo.this, "Done!", Toast.LENGTH_SHORT) 
     .show(); 
    } 
    } 
}