背景リスト

遅いソース(たとえば、HTTPリクエスト)から大きなリストを読み込む場合、特にユーザーが必要とするデータが少ない(検索結果、ニュース記事)場合は、リスト全体を一度にダウンロードしても意味がありません。 この場合、ページネーションリストのロードを実装することをお勧めします。 この記事では ListViewコントロールのフッタービューを使用した簡単な方法を示します。 リストとそのアダプターが既にあり、それが例えば非同期HTTPリクエストを使用して要素(最初の数個、またはすべて)をロードすることは理解されています。 次のページをロードする機能を追加できる別のクラスでデータ要求を作成する方が便利です。



アクションプラン



  1. ロードプロセスに関するメッセージ要素のレイアウトを準備する
  2. ListViewコントロールの準備
  3. 次のページをリストアダプターに読み込むためのスタートアップコードを追加する
  4. 次のページを読み込んだ結果を処理します




ロードプロセスに関するメッセージ要素のレイアウトを準備する



テキスト "Loading ..."で設定されたindeterminateOnlyTextViewフラグを持つ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();
      
      






All Articles