ListViewで表示される分だけデータをロードする
以前の記事でも紹介しているようにListViewでは文字や画像を表示することができます。
しかし、Adapterを単純にListViewに設定してしまうと1度に画面に表示できないデータも
ロードしてしまうため、データの数が多い場合はデータのロードに時間がかかってしまいます。
通常、1画面に表示できるデータは限られていますので、
表示できる分だけデータをロードすれば不要なデータはロードする必要がなくなり、
ロード時間を短縮することができます。
詳細な説明は続きをご覧下さい。
ポイントは画面に表示するべきデータ数だけをロードして、
画面がスクロールしたら必要なデータだけをロードすることです。
これを実現するためには画面のスクロールを検知する必要があります。
ListViewの基本的な使い方については「リストビューを使ってデータを一覧表示する」をご覧下さい。
ListView.OnScrollListener
ListView.OnScrollListenerを使うことで、
ListViewのスクロール状態を検知できるので、
スクロールしたときに表示するべきデータを選別できるようにします。
まず、クラスにListView.OnScrollListenerインタフェースを実装します。
1 | public class slowLoadList extends ListActivity implements ListView.OnScrollListener |
次にonScrollStateChangedメソッドをオーバーライドします。
onScrollStateChangedメソッドはスクロールの状態を検知するためのメソッドです。
以下のようにスクロール中と画面をはじいたときにはフラグを立ててデータを表示しないようにして、
スクロールが終わったときにフラグを外してデータを表示するようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // スクロールの状態を検知する 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と表示させます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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; } |