编辑 - 请先阅读!
事实证明,我犯了一个非常愚蠢的错误。我的布局包含一个与ListView具有完全相同背景颜色的WebView。WebView在活动加载后的某个时间点被隐藏,但我忘记在方向更改后隐藏它,所以它覆盖了ListView并使它看起来像是空的,而实际上它已正确加载。我将把这个问题留在这里,因为它提供了一个关于如何在方向更改后恢复ListView数据的工作示例:)
---------------------------------
嗯,这在当时似乎很容易。我正在尝试在方向更改后恢复 ListView 上的数据。数据是从 Web 服务中获取的,所以起初我只是在更改发生后调用 Web 服务。这工作正常,但是对于如此简单的情况,重新获取数据太慢了,所以我想我宁愿保存 ListView 的状态,然后直接恢复它而不必返回服务器。
我正在使用onSaveInstanceState执行此操作:
protected void onSaveInstanceState (Bundle outState) {
ListAdapter adapter = this.listView.getAdapter();
if (adapter != null) {
try {
String dataSource = ((JSONArrayAdapter)adapter).getDataSource().toString(1);
outState.putString("dataSource", dataSource);
} catch (Exception e) {
Log.w("MainActivity", "Invalid data adapter", e);
}
}
}
JSONArrayAdapter是我正在使用的自定义适配器,它使用JSONArray对象作为其数据源。我知道它可以工作,因为它在方向改变之前正确显示了所有内容。
将 ListView 数据保存为 JSON 字符串后,我尝试使用onCreate恢复它:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.listView);
progressBar = (ProgressBar)findViewById(R.id.progressBar);
String dataSource = null;
if (savedInstanceState != null) {
dataSource = savedInstanceState.getString("dataSource");
}
if (dataSource == null) {
reloadList(); //this is a call to the web service
} else {
try {
JSONArray array = new JSONArray(dataSource);
this.listView.setAdapter(new JSONArrayAdapter(getApplicationContext(), array));
this.progressBar.setVisibility(View.GONE);
} catch (JSONException e) {
Log.w("MainActivity", "Invalid data adapter", e);
reloadList();
}
}
}
结果是我翻转了设备并且没有错误,但是 ListView 是空的(或者它的项目至少是不可见的)。使用调试器,我已验证 JSON 字符串是否正确存储。我什至通过适配器上的getView方法来确保正确生成视图。还值得注意的是,代码没有进入任何 catch 块。有谁知道是什么导致 ListView 为空?谢谢