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()));