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;
}
