我有一个相当令人费解的问题。如果我尝试使用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。
谢谢!
答案 0 :(得分:1)
如果您的数据是ArrayList<String>
,则可以在onCreate()
中分配data = new ArrayList<String>();
并为其分配适配器,这将使ListView保持空白,直到您完成asynctask,您可以分配包含您的值的数据,并使用此adapter.notifyDataSetChanged()
通知适配器数据已更改。
答案 1 :(得分:0)
听起来好像你需要在填充后调用适配器上的notifyDataSetChanged()。必须从UI线程调用它,因此将其放入直接从postExecute()方法调用的代码中。
如果这有帮助,请将此标记为答案。