前言:最近涉及到和QQ打交道,定义所有的好友一共只能有300条消息,如果一次性从数据库读取300条或者更多,界面会有细微的卡顿.所以考虑了下分页,第一次进来只显示20条(仿微信),当用户滑到第一条后,如果数据库有消息,则再加载20条.
##步骤-问把大象关冰箱,总共分几步?
###1.自定义absListview.scrollListerner
核心的东西是监听ListView的scrollListerner,网上扒了一个挺不错的,大家用的时候实现这个scrollListerner,完善自己的逻辑即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| public class MyOnScrollListener implements OnScrollListener { private int totalItemCount; private int lastItem; private int firstItem; private boolean isLoading; private View footer; private OnloadDataListener listener; private List<MsgBean> data; Handler handler = new Handler(); public MyOnScrollListener(View footer, List<MsgBean> data) { this.footer = footer; this.data = data; } public void setOnLoadDataListener(OnloadDataListener listener) { this.listener = listener; }
@Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (!isLoading && firstItem == 0 && scrollState == SCROLL_STATE_IDLE) { footer.setVisibility(View.VISIBLE); handler.postDelayed(new Runnable() { @Override public void run() { if (listener != null) { loadMoreData(); listener.onLoadData(data); loadComplete(); } } }, 2000); } }
private void loadComplete() { isLoading = false; footer.setVisibility(View.GONE); }
private void loadMoreData() { isLoading = true; MsgBean msg = null; for (int i = 0; i < 3; i++) { msg = new MsgBean(); msg .setRemark("Liming"+i); msg .setMsgID(i); data.add(stu); } }
@Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { lastItem = firstVisibleItem + visibleItemCount; firstItem = firstVisibleItem; this.totalItemCount = totalItemCount; } public interface OnloadDataListener { void onLoadData(List<MsgBean> data); } }
|
###2.实现此接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class ListPageActivity extends Activity implements MyOnScrollListener.OnloadDataListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_page); showListView(data); MyOnScrollListener onScrollListener = new MyOnScrollListener(header, data); onScrollListener.setOnLoadDataListener(this); mListView.setOnScrollListener(onScrollListener);
@Override public void onLoadData(List<MsgBean> data) { showListView(data); } }
|
showListView里面无疑是普通的更新adapter的工作
那么我们如何借助xutils的数据库进行分类呢?
###3.利用xutils数据库操作进行分页处理
首先,我们理一下思路,上面我们已经实现了上拉的回调,在此回调中把新来的数据加载到adapter即可.
//下文db是Dbmanager的实例,可参考xutils3用法
/**
* 当前屏幕显示的消息数量
*/
private int MAX_MSG_NUMBER = 20;
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| private List<MsgBean> getDataFromDb() {
List<?> dbSize = db.selector(MsgBean.class).where(WhereBuilder.b("id", "=", 400)).findAll();
if (dbSize.size() < MAX_MSG_NUMBER) { indexOffset = 0; } else { indexOffset = dbSize.size() - MAX_MSG_NUMBER; } List<MsgBean> datas = db.selector(MsgBean.class).where(WhereBuilder.b("id", "=", 400)).limit(MAX_MSG_NUMBER) .offset(indexOffset).findAll(); return datas; }
|
这里解释一下
db.selector(MsgBean.class).where(WhereBuilder.b("id", "=", 400)).limit(MAX_MSG_NUMBER).offset(indexOffset).findAll();是我们实现分页的关键
.limit是我们定义的分页大小
.offset偏移量,我们数据库的大小是不变的,如果不定义偏移量,那么我们定义的分页大小每次只从0取到19.假设数据库中有21条数据,那么我们需要从1取到20,而不是0到19,所以偏移1.
然后我们在loadMoreData中
MAX_MSG_NUMBER += MAX_MSG_NUMBER;
getDataFromDb();
将大小自加,即完成加载更多的功能,在onLoadData(List data)中加载数据即可.
后面贴上我对xutils数据库操作的封装,还有很多不完善之处
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
public class DbUtil { private static final String TAG = DbUtil.class.getName(); private static DbUtil dbUtil; private DbManager db; private DbUtil(){ db = x.getDb(MyApplication.getInstance().daoConfig); } public static DbUtil getInstance(){ if(dbUtil == null){ synchronized (DbUtil.class) { if(dbUtil == null){ dbUtil = new DbUtil(); } } } return dbUtil; }
public void addMsgList(List<MsgBean> list) { try { db.saveOrUpdate(list); } catch (DbException e) { e.printStackTrace(); LogHelper.e(TAG, e.getMessage()); } }
public void addMsgToDb(MsgBean node) { try { db.saveOrUpdate(node); } catch (DbException e) { e.printStackTrace(); LogHelper.e(TAG, e.getMessage()); } }
public void deleteAll(Class cls) { try { db.delete(cls); } catch (DbException e) { LogHelper.e(TAG, e.getMessage()); e.printStackTrace(); } }
@SuppressWarnings("unchecked") public void deleteFirst(Class cls){ try { db.delete(db.findFirst(cls)); } catch (DbException e) { e.printStackTrace(); } }
@SuppressWarnings("unchecked") public List<?> findAll(Class cls) { try { return db.findAll(cls) == null ? Collections.emptyList() : db.findAll(cls); } catch (DbException e) { e.printStackTrace(); LogHelper.e(TAG, e.getMessage()); return Collections.emptyList(); } }
@SuppressWarnings("unchecked") public List<?> findDataByWhere(Class cls,WhereBuilder format){ try { return db.selector(cls).where(format).findAll()== null ? Collections.emptyList() :db.selector(cls).where(format).findAll(); } catch (DbException e) { LogHelper.e(TAG, e.getMessage()); e.printStackTrace(); return Collections.emptyList(); } }
@SuppressWarnings("unchecked") public Selector<?> findDataBySelector(Class cls,WhereBuilder format){ try { return db.selector(cls).where(format); } catch (DbException e) { e.printStackTrace(); } return null; } }
|