SimpleCursorAdapter スクロール順次読み出し

SimpleCursorAdapter を使った時に、スクロールさせた時に順々に読み出して表示する方法
Google Play みたいなことを ListView を作りたくて書いてみた。

まずは、DBにスクロールで表示する分のクエリ実行を持つインターフェース
他のメソッドが必要なら、このインターフェースを継承したインタフェースや抽象クラスを用意すればよい。

import android.database.Cursor;
/**
 * QuerySQLite
 */
public interface QuerySQLite{
   public Cursor queryForScroll(int offset,int limit);
}


次に、ListView setOnScrollListener で、登録する AbsListView.OnScrollListener を定義、、、

import android.database.Cursor;
import android.os.AsyncTask;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
/**
 * SimpleScrollListener
 */

public class SimpleScrollListener implements AbsListView.OnScrollListener{
   ListView listview;
   QuerySQLite querySQLite;
   SimpleCursorAdapter simpleadapter;
   int limit;
   int offset = 0;
   private int firstVisible;
   View footerreadingView;
   private AsyncTask<Integer,Void,Cursor> nextReadTask;

   /**
    * コンストラクタ
    * @param listview SimpleCursorAdapter をセットした ListView
    * @param adapter SimpleCursorAdapter
    * @param querySQLite QuerySQLite
    * @param limit 1度に表示させる数
    * @param footerreadingView 最後尾に出す読込中の View
    */

   public  SimpleScrollListener(ListView listview,SimpleCursorAdapter adapter
,QuerySQLite querySQLite,int limit,View footerreadingView){
      this.listview = listview;
      this.simpleadapter = adapter;
      this.querySQLite = querySQLite;
      this.limit = limit;
      this.footerreadingView = footerreadingView;
   }
   @Override
   public void onScrollStateChanged(AbsListView view,int scrollState){

      if (firstVisible==0 && scrollState==AbsListView.OnScrollListener.SCROLL_STATE_FLING){
         offset -= limit;
         if (offset < 0) offset = 0;
         new AsyncTask<Integer,Void,Cursor>(){
            @Override
            protected Cursor doInBackground(Integer...params) {
               return querySQLite.queryForScroll(params[0],params[1]);
            };
            @Override
            protected void onPostExecute(Cursor result){
               simpleadapter.changeCursor(result);
               simpleadapter.notifyDataSetInvalidated();

            };
         }.execute(offset,limit);
      }
   }
   @Override
   public void onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount){

      firstVisible = firstVisibleItem;
      if ((firstVisibleItem+visibleItemCount)==totalItemCount){
         // 最後尾に到達、 既に読み込み中ならスキップ
         if (nextReadTask != null && nextReadTask.getStatus()==AsyncTask.Status.RUNNING){
            return;
         }
         offset += limit;
         nextReadTask = new AsyncTask<Integer,Void,Cursor>(){
            @Override
            protected Cursor doInBackground(Integer...params) {
               return querySQLite.queryForScroll(params[0],params[1]);
            };
            @Override
            protected void onPostExecute(Cursor result){
               if (result.getCount() > 0){
                  simpleadapter.changeCursor(result);
                  simpleadapter.notifyDataSetInvalidated();

               }else{
                  // 後ろにレコード無し
                  offset -= limit;
                  listview.removeFooterView(footerreadingView);
               }
            };
         }.execute(offset,limit);
      }
   }
}


使い方のサンプル以下のように。。。(かなり省略。。)

SimpleCursorAdapter simpleadapter = // 省略

listview.setOnScrollListener(new SimpleScrollListener(listview,simpleadapter,querySQLite,limits,getFooterView()));