遅いソース(たとえば、HTTPリクエスト)から大きなリストを読み込む場合、特にユーザーが必要とするデータが少ない(検索結果、ニュース記事)場合は、リスト全体を一度にダウンロードしても意味がありません。 この場合、ページネーションリストのロードを実装することをお勧めします。 この記事では
、 ListViewコントロールの
フッタービューを使用した簡単な方法を示します。 リストとそのアダプターが既にあり、それが例えば非同期HTTPリクエストを使用して要素(最初の数個、またはすべて)をロードすることは理解されています。 次のページをロードする機能を追加できる別のクラスでデータ要求を作成する方が便利です。
アクションプラン
- ロードプロセスに関するメッセージ要素のレイアウトを準備する
- ListViewコントロールの準備
- 次のページをリストアダプターに読み込むためのスタートアップコードを追加する
- 次のページを読み込んだ結果を処理します
ロードプロセスに関するメッセージ要素のレイアウトを準備する
テキスト "Loading ..."で設定された
indeterminateOnlyと
TextViewフラグを持つ2つの
ProgressBar要素を持つレイアウトxmlを作成します。 それらを水平のLinearLayoutに配置します。 ブート情報の空のリストに既製のレイアウトを使用することもできます。
ListViewの準備
準備したレイアウトをダウンロードし、ListViewの地下に設定します。 これは、setAdapterメソッドを呼び出す前に行う必要があります。 リストの最後に達したときに削除するアイテムへのリンクを保存することを忘れないでください。
private LinearLayout mLoadingFooter; @Override protected void onCreate(Bundle savedInstanceState) { ... LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mLoadingFooter = (LinearLayout) layoutInflater.inflate(R.layout.loading, null); mList = (ListView) findViewById(R.id.list); mList.addFooterView(mLoadingFooter); ... }
次のページをリストアダプターに読み込むためのスタートアップコードを追加する
次のページのロードを開始するには、リストアダプターの
getViewメソッドを使用します。リストの最後の要素が要求された場合は、次のページをロードします。 ブートプロセスを別のスレッドに削除してから、現在のアクティビティにIntentをスローすると便利です。 ロード中にアダプターによってアクセスされるデータが変更される場合、
notifyDataSetInvalidatedを呼び出すことを忘れないでください。
@Override public View getView(int position, View convertView, ViewGroup parent) { ... if (position == getCount() - 1 && hasNextPage()) { loadNextPage(); } }
UPD: grishkaaはAbsListView.OnScrollListenerを使用するより正確な方法を推奨し
ました :
mList.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView arg0, int arg1) {} @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (visibleItemCount > 0 && firstVisibleItem + visibleItemCount == totalItemCount && hasNextPage()) { loadNextPage(); } } });
次のページを読み込んだ結果を処理します
インテントは匿名の
BroadcastReceiverによってインターセプトされ、
ハンドラーに渡されます(UIスレッドで実行されます)。 アダプタの
notifyDataSetChangedメソッドを呼び出して、最後のページが読み込まれた場合にのみ
フッターを削除できます。
if (!hasNextPage() && mList.getFooterViewsCount() > 0) { mList.removeFooterView(mLoadingFooter); } mAdapter.notifyDataSetChanged();