読者です 読者をやめる 読者になる 読者になる

φ(.. )メモシテオコウ AndroidのListViewで最下部までスクロールしたらデータの更新する場合のめも

AndroidのListViewで最下部までスクロールしたらデータの更新したい場合、インターフェースクラスのandroid.widget.AbsListView.OnScrollListenerをimplementsして以下の2関数をオーバーライドするのがセオリーっぽいですね。

  • void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
  • void onScrollStateChanged(AbsListView view, int scrollState);

そしてonScroll()内でデータ数と(firstVisibleItem+visibleItemCount)を比較して同じになってたら最下部まで着たという判断ですがこれだと連続で処理が走る場合があったのでちょっと修正。
どんな時にあったかというと画面遷移でデータをリフレッシュ下後にデータ数が1画面で収まるような場合にonScroll()が呼ばれていてそこで判断条件がtrueになって2度処理が呼ばれるとかでした。他にもデータの最後の方で取得したデータ数が少ない場合とか。

使ってるListViewはAndroidのそのままではなくてpulltorefreshというPull to Refresh(ツイッタークライアントみたいにリストの上部でプルダウンすると更新処理が走るやつです)のライブラリを使ってますが。。

@Override
void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
    if (data.size() == firstVisibleItem + visibleItemCount) {
        // do something
    }

最下部まで着たという判断方法は変えずに、if文内では「処理する必要があるよフラグ」をtrueにしておいて処理はonScrollStateChanged()から呼ぶようにし下記みたいな感じで対応してみました。

@Override
void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
    if (this.data.size() == firstVisibleItem + visibleItemCount) {
        this.flg = true;
    }
}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) 
{
    if (this.flg && scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
         // do something
    }
}

onScroll()はスクロール中は何回か呼ばれるし、ここで処理するよりもOnScrollListener.SCROLL_STATE_IDLEはスクロールが終わった状態なのを確認してから処理するほうが安全ですねということで。