ListViewで表示される分だけデータをロードする
以前の記事でも紹介しているようにListViewでは文字や画像を表示することができます。
しかし、Adapterを単純にListViewに設定してしまうと1度に画面に表示できないデータも
ロードしてしまうため、データの数が多い場合はデータのロードに時間がかかってしまいます。
通常、1画面に表示できるデータは限られていますので、
表示できる分だけデータをロードすれば不要なデータはロードする必要がなくなり、
ロード時間を短縮することができます。
詳細な説明は続きをご覧下さい。
ポイントは画面に表示するべきデータ数だけをロードして、
画面がスクロールしたら必要なデータだけをロードすることです。
これを実現するためには画面のスクロールを検知する必要があります。
ListViewの基本的な使い方については「リストビューを使ってデータを一覧表示する」をご覧下さい。
ListView.OnScrollListener
ListView.OnScrollListenerを使うことで、
ListViewのスクロール状態を検知できるので、
スクロールしたときに表示するべきデータを選別できるようにします。
まず、クラスにListView.OnScrollListenerインタフェースを実装します。
public class slowLoadList extends ListActivity implements ListView.OnScrollListener
次にonScrollStateChangedメソッドをオーバーライドします。
onScrollStateChangedメソッドはスクロールの状態を検知するためのメソッドです。
以下のようにスクロール中と画面をはじいたときにはフラグを立ててデータを表示しないようにして、
スクロールが終わったときにフラグを外してデータを表示するようにします。
// スクロールの状態を検知する public void onScrollStateChanged(AbsListView view, int scrollState) { switch (scrollState) { // スクロールしていない case OnScrollListener.SCROLL_STATE_IDLE: // スクロール中であることを示すフラグをfalseに mBusy = false; // ListViewの表示するべきデータ位置を取得 int first = view.getFirstVisiblePosition(); int count = view.getChildCount(); // ListViewに表示するべきデータを設定する for (int i = 0; i < count; i++) { TextView t = (TextView) view.getChildAt(i); if (t.getTag() != null) { t.setText(mStrings[first + i]); t.setTag(null); } } break; // スクロール中 case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: mBusy = true; break; // はじいたとき case OnScrollListener.SCROLL_STATE_FLING: mBusy = true; break; } }
あとは、adapterのgetViewメソッドの実装を以下のようにします。
スクロール中であればデータを表示せずにLoadingと表示させます。
public View getView(int position, View convertView, ViewGroup parent) { TextView text; if (convertView == null) { text = (TextView) mInflater.inflate( android.R.layout.simple_list_item_1, parent, false); } else { text = (TextView) convertView; } // スクロール中でなければデータを表示する if (!mBusy) { text.setText(mStrings[position]); text.setTag(null); // スクロール中であればデータを表示せずにLoadingと表示 } else { text.setText("Loading..."); // Non-null tag means the view still needs to load it's data text.setTag(this); } return text; }