2012-04-19 89 views
3

我有一個相當令人費解的問題。如果我嘗試使用AsyncTask填充ListView,則該ListView的適配器上的getView()永遠不會被調用。請注意,這是活動啓動時此ListView的初始數據總量。 AsyncTask是需要的,因爲ListView是從HTTP填充的。ListView的適配器getView()不調用,如果填充後onCreate()

我有以下簡單的佈局:

<?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="wrap_content" 
    > 
<ListView 
    android:id="@+id/transactionListView" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:divider="#CCCCCC" 
    android:dividerHeight="1px" 
    /> 
</LinearLayout> 

而一個基本的onCreate():

public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    mainListView = (ListView)findViewById(R.id.transactionListView); 
    this.populateListView(); 
} 

,你可以看到來電:

private void populateListView() 
{ 
    populateListViewTask task = new populateListViewTask(); 
    task.execute(); 
} 

最後,的AsyncTask onPostExecute():

protected void onPostExecute(Void result) 
{ 
    lvAdapter = new CustomArrayAdapter(MainActivity.this, R.layout.listitem, data); 
    mainListView.setAdapter(lvAdapter); 
} 

當然,實際的實現比這更復雜一點,但是我沒有任何其他的錯誤來源,除了getView()沒有在上面的配置中被調用。如果在onPostExecute()中添加lvAdapter.getCount(),我會得到30(這是我所期望的,因爲實際代碼的HTTP/XML解析部分工作正常)。我也嘗試添加notifyDataSetChanged(),只是爲了微笑,但是顧名思義,CustomArrayAdapter就是擴展了ArrayAdapter。我也嘗試在視圖上invalidate(),也沒有效果。

但是,如果ALTER的onCreate()來調用的AsyncTask之前有像這樣一個單一的虛擬列表項:

public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    mainListView = (ListView)findViewById(R.id.transactionListView); 

    //Add dummy list item 
    TestDataStructure[] data = new TestDataStructure[1];| 
    data[0] = new TestDataStructure(); 
    data[0].item = "Dummy List Item"; 
    lvAdapter = new CustomArrayAdapter(MainActivity.this, R.layout.listitem, data); 
    mainListView.setAdapter(lvAdapter); 

    this.populateListView(); 
} 

getView()隨後將在onPostExecute()調用後正確調用,ListView控件將使用AsyncTask中的新項目正確填充。我的直覺是,在最初的情況下,Android在Activity創建週期中確定了佈局中項目的結構和可見性,並決定了transactionListView因爲它是空的而不可見,從而阻止它在新的適配器時調用getView()已設置。

有關如何解決此問題的任何想法,而不添加虛擬列表項(當然,直到AsyncTask完成後纔可見)?我的活動擴展了Activity,而不是ListActivity。

謝謝!

+0

解決了您的問題? – 2012-04-19 01:27:39

回答

0

聲音和看起來像你需要在適配器填充後調用notifyDataSetChanged()。這必須從UI線程調用,因此將其放入直接從postExecute()方法調用的代碼中。

如果有幫助,請將此標記爲答案。

+0

如果您在我上面的原始問題中註明,我已經嘗試過,但沒有成功。我不認爲notifyDataSetChanged()對ArrayAdapter有任何影響。 – Nishmaster 2012-04-19 01:35:53

1

如果你的數據是ArrayList<String>,您可以在onCreate()這個data = new ArrayList<String>();分配和分配與此適配器,這將讓你的ListView空的,直到你完成的AsyncTask,你可以用你的價值觀指派的數據,並通知適配器的數據已更改此adapter.notifyDataSetChanged()

+0

不幸的是,數據是一個對象數組,當我加載虛擬物品時,getView()試圖立即採取行動。因此,我無法將任何空值傳遞給發往適配器的數據。 – Nishmaster 2012-04-19 01:52:36

+1

@Nishmaster:當您在等待AsyncTask完成工作時,將適配器的數據設置爲'new ArrayList ()'。就您的具體問題而言,我將您的示例代碼放入一個虛擬項目中,看起來沒有問題。我也在做一些與你在我自己的項目中描述的東西非常相似的東西(ArrayAdapter有自定義對象類型和所有東西),並且沒有看到這個問題,也沒有你報告的notifyDataSetChanged()問題。聽到這不是一個有趣的答案,但也許錯誤源於代碼中的其他位置? – CloudyMusic 2012-04-19 22:38:48

相關問題