我有一个相当令人费解的问题。如果我尝试使用 AsyncTask 填充 ListView,则永远不会调用该 ListView 适配器上的 getView()。请注意,这是 Activity 启动时此 ListView 的初始数据填充。AsyncTask 是必需的,因为 ListView 是从 HTTP 填充的。
我有以下简单的布局:
<?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() ,也没有效果。
但是,如果在调用 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();
}
getView() 将在 onPostExecute() 调用之后正确调用,ListView 将使用来自 AsyncTask 的新项目正确填充。我的预感是,在原来的情况下,Android 在 Activity 创建周期中确定了布局中项目的结构和可见性,并决定 transactionListView 因为它是空的而不可见,从而阻止它在新适配器时调用 getView()已设置。
关于如何在不添加虚拟列表项的情况下解决此问题的任何想法(在 AsyncTask 完成之前当然可见)?我的活动扩展了 Activity,而不是 ListActivity。
谢谢!