如果在onCreate()之后填充,则不会调用ListView适配器getView()

时间:2012-04-19 01:21:34

标签: android listview android-asynctask

我有一个相当令人费解的问题。如果我尝试使用AsyncTask填充ListView,则从不调用该ListView适配器上的getView()。请注意,这是Activity启动时此ListView的初始数据量。从HTTP填充ListView时需要AsyncTask。

我有以下简单的布局:

<?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(),仅用于grins,但正如名称所示,CustomArrayAdapter扩展了ArrayAdapter。我也在视图上尝试了invalidate(),也没有效果。

但是,如果在调用AsyncTask之前将onCreate()改为拥有一个像这样的虚拟列表项:

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();
}
然后在onPostExecute()调用之后正确调用

getView(),并且ListView将使用AsyncTask中的新项正确填充。我的预感是,在最初的情况下,Android在Activity创建周期中确定布局中项目的结构和可见性,并确定transactionListView不可见,因为它是空的,从而阻止它在新的适配器时调用getView()已经确定了。

关于如何在不添加虚拟列表项的情况下修复此问题的任何想法(在AsyncTask完成之前当然可见)?我的活动扩展了Activity,而不是ListActivity。

谢谢!

2 个答案:

答案 0 :(得分:1)

如果您的数据是ArrayList<String>,则可以在onCreate()中分配data = new ArrayList<String>();并为其分配适配器,这将使ListView保持空白,直到您完成asynctask,您可以分配包含您的值的数据,并使用此adapter.notifyDataSetChanged()通知适配器数据已更改。

答案 1 :(得分:0)

听起来好像你需要在填充后调用适配器上的notifyDataSetChanged()。必须从UI线程调用它,因此将其放入直接从postExecute()方法调用的代码中。

如果这有帮助,请将此标记为答案。