我有一个相当令人费解的问题。如果我尝试用 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 的扩展。我还在 View 上尝试了 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 扩展了 Activity,而不是 ListActivity。
谢谢!
最佳答案
如果你的数据是ArrayList<String>
, 你可以在 onCreate()
中赋值这个data = new ArrayList<String>();
并以此分配适配器,这将使您的 ListView 保持为空,直到您完成异步任务,您可以使用您的值分配数据,并通知适配器数据已被更改 adapter.notifyDataSetChanged()
.
关于android - 如果在 onCreate() 之后填充,则不会调用 ListView 适配器 getView(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10220386/