編集 - 最初に読んでください!
私は非常にばかげた間違いを犯していたことが判明しました。私のレイアウトには、 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 が空になる原因を知っている人はいますか? ありがとう