アクションプラン
- ロードプロセスに関するメッセージ要素のレイアウトを準備する
- 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();