7

我需要用來自網絡的數據填充長的ListView,比如說整個數據收集需要2-3秒。我不希望用戶看到加載Dialog並等待整個列表下載。相反,我想更新ListView隨着每個項目變得可用。如何將行添加到列表視圖異步?

  • 我該怎麼做?
  • 我推測加入ArrayAdapterAsyncTaskOnProgressUpdate
  • 我必須在每增加一行後發出notifyDatasetChanged()嗎?
  • Fragment/Loader方法更好嗎?
  • 是否有像這樣的案例 的教程或API演示參考實現?

這不是重要的是,數據的Activity模具(即Service是不必要的)

+0

使用從支持庫ListFragment,看樣品,緩存在私有字段數據然後調用notifyDatasetChanged當一個新的元素是準備 – sherpya 2012-08-16 21:24:24

+0

定義「慢慢來」。你是在一個很大的時間間隔取得,還是它本身是一個大的下載? – 2012-08-16 21:24:27

回答

3

迄今爲止所見到的最佳方法是從CommonsWare。它被發現在這個相關的answer

顯然,沒有notifyDatasetChanged()的電話add沒有任何問題。

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

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

我想你可以從這裏開始之前完全獲取:http://www.vogella.com/articles/AndroidPerformance/article.html

所以,你需要做的異步調用到服務器的數據。 或者你可以運行一個後臺任務。

你可以谷歌的AsyncTask或在這裏搜索stackoverflow。 這裏是例子:AsyncTask Android example

+0

這兩個鏈接中的哪一個顯示如何異步添加單個行,而不是等到所有行都被填充?我沒有看到任何回答這個問題的鏈接。 – 2012-08-17 02:04:27

+0

鏈接是信息,如何在後臺線程中做一個工作。還有一些信息,如何更新GUI。您無法從後臺線程更新GUI元素。在第二個鏈接是TextView的例子。 – Guntis 2012-08-17 06:14:45

0

只是爲了確保,ListViewadapter及其底層數據不能從線程以外的UI線程更新。必須在主應用程序線程上執行更新。 非UI線程可以使用post()runOnUiThread()等來調用更新。

調用notifyDatasetChanged()就像這不是很好的做法,應該由Adapter本身或改變數據的對象調用。

由於網絡運行緩慢,請考慮是否不希望在database中存儲下載的數據。比你結束實施某種CursorAdapter,最好與使用Loader,以便當您在您的工作線程中更新database時,ListView將自動通知有關更改。

+0

我正在詢問顯示數據和更新ListView,因爲它變得可用,而不是預先收集並存儲它。 – 2012-08-17 02:07:37

+0

當您的物品變得可用時,將其插入到'database'中,並且'ListView'將被通知有關更改,在這種情況下,提及的物品已添加,除非您未在一個事務中插入所有物品。 – biegleux 2012-08-17 04:09:04