11

Sto utilizzando un ArrayAdapter per aggiungere elementi a un ListView personalizzato e mostrare i risultati nella mia app per Android. Il problema che sto avendo è che l'ArrayAdapter sembra aspettare fino a quando tutti gli elementi sono in esso prima che mostri la vista. Vale a dire, quando aggiungo gli elementi all'ArrayAdapter e chiamo notifyDataSetChanged, non aggiorna il ListView per mostrare l'elemento aggiunto. Aspetta fino a quando non vengono aggiunti tutti gli elementi e GetView viene chiamato prima di mostrare gli elementi.Android - Aggiunta e visualizzazione di elementi a ListView uno alla volta utilizzando un ArrayAdapter

Quello che vorrei fare è mostrare l'elemento immediatamente dopo averlo aggiunto a ListView. È possibile?

credo che il codice in questione è la seguente:

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

Come si può vedere, anche se io chiamo notifyDataSetChanged dopo il metodo Add, che in realtà non aggiornare la visualizzazione. Dopo aver terminato il ciclo sopra riportato, la vista viene finalmente aggiornata (in base a ciò che so, perché GetView non viene chiamato fino a quando non viene completata questa sezione del codice).

Ho provato a ignorare il metodo di aggiunta del mio ArrayAdapter personalizzato senza fortuna, dal momento che non ho accesso alla vista in quel metodo.

Qualsiasi aiuto sarebbe gradito :)

Bara

risposta

23

interfaccia utente di Android è single-threaded. Non stai restituendo il controllo ad Android dal thread principale dell'applicazione ogni volta che aggiungi una voce all'adattatore. Quindi, Android non ha la possibilità di visualizzare le voci finché non restituisci il controllo e non lo fai finché non hai compilato l'adattatore nella sua interezza.

Here is an example mostrando l'uso di un AsyncTask per riempire un ArrayAdapter progressivamente tramite un thread in background.

/*** 
    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(); 
    } 
    } 
} 
Problemi correlati