android ListView結(jié)合xutils3仿微信實現(xiàn)下拉加載更多
前言:最近涉及到和QQ打交道,定義所有的好友一共只能有300條消息,如果一次性從數(shù)據(jù)庫讀取300條或者更多,界面會有細微的卡頓.所以考慮了下分頁,第一次進來只顯示20條(仿微信),當(dāng)用戶滑到第一條后,如果數(shù)據(jù)庫有消息,則再加載20條.
步驟-問把大象關(guān)冰箱,總共分幾步?
1.自定義absListview.scrollListerner
核心的東西是監(jiān)聽ListView的scrollListerner,這里采取拿來主義 原文連接找不到了,如果原作者看到,請聯(lián)系青樓愛小生,將您的文章鏈接更新出來 ,網(wǎng)上扒了一個挺不錯的,大家用的時候?qū)崿F(xiàn)這個scrollListerner,完善自己的邏輯即可
public class MyOnScrollListener implements OnScrollListener {
private int totalItemCount;
//ListView最后的item項
private int lastItem;
//listview第一項
private int firstItem;
//用于判斷當(dāng)前是否在加載
private boolean isLoading;
//底部加載更多布局
private View footer;
//接口回調(diào)的實例
private OnloadDataListener listener;
//數(shù)據(jù)
private List<MsgBean> data;
Handler handler = new Handler();
public MyOnScrollListener(View footer, List<MsgBean> data) {
this.footer = footer;
this.data = data;
}
//設(shè)置接口回調(diào)的實例
public void setOnLoadDataListener(OnloadDataListener listener) {
this.listener = listener;
}
/**
* 滑動狀態(tài)變化
*
* @param view
* @param scrollState 1 SCROLL_STATE_TOUCH_SCROLL是拖動 2 SCROLL_STATE_FLING是慣性滑動 0SCROLL_STATE_IDLE是停止 , 只有當(dāng)在不同狀態(tài)間切換的時候才會執(zhí)行
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
//如果數(shù)據(jù)沒有加載,并且滑動狀態(tài)是停止的,并且滾到了第一個item,可在此做下拉更新或者上拉更新的判斷
if (!isLoading && firstItem == 0 && scrollState == SCROLL_STATE_IDLE) {
//顯示加載更多
footer.setVisibility(View.VISIBLE);
//模擬一個延遲兩秒的刷新功能
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (listener != null) {
//開始加載更多數(shù)據(jù)
loadMoreData();
//回調(diào)設(shè)置ListView的數(shù)據(jù)
listener.onLoadData(data);
//加載完成后操作什么
loadComplete();
}
}
}, 2000);
}
}
/**
* 當(dāng)加載數(shù)據(jù)完成后,設(shè)置加載標(biāo)志為false表示沒有加載數(shù)據(jù)了
* 并且設(shè)置底部加載更多為隱藏
*/
private void loadComplete() {
isLoading = false;
footer.setVisibility(View.GONE);
}
/**
* 開始加載更多新數(shù)據(jù),這里每次只更新三條數(shù)據(jù)
*/
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);
}
}
/**
* 監(jiān)聽可見界面的情況
*
* @param view ListView
* @param firstVisibleItem 第一個可見的 item 的索引
* @param visibleItemCount 可以顯示的 item的條數(shù)
* @param totalItemCount 總共有多少個 item
*/
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
//實現(xiàn)下拉加載
lastItem = firstVisibleItem + visibleItemCount;
//實現(xiàn)上拉加載
firstItem = firstVisibleItem;
//總listView的item個數(shù)
this.totalItemCount = totalItemCount;
}
//回調(diào)接口
public interface OnloadDataListener {
void onLoadData(List<MsgBean> data);
}
}
2.實現(xiàn)此接口
public class ListPageActivity extends Activity implements MyOnScrollListener.OnloadDataListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_page);
//顯示到ListView上
showListView(data);
//自定義的滾動監(jiān)聽事件
MyOnScrollListener onScrollListener = new MyOnScrollListener(header, data);
//設(shè)置接口回調(diào)
onScrollListener.setOnLoadDataListener(this);
//設(shè)置ListView的滾動監(jiān)聽事件
mListView.setOnScrollListener(onScrollListener);
@Override
public void onLoadData(List<MsgBean> data) {
//加載數(shù)據(jù)完成后,展示數(shù)據(jù)到ListView
showListView(data);
}
}
showListView里面無疑是普通的更新adapter的工作
那么我們?nèi)绾谓柚鷛utils的數(shù)據(jù)庫進行分類呢?
3.利用xutils數(shù)據(jù)庫操作進行分頁處理
首先,我們理一下思路,上面我們已經(jīng)實現(xiàn)了上拉的回調(diào),在此回調(diào)中把新來的數(shù)據(jù)加載到adapter即可.
下文db是Dbmanager的實例
/** * 當(dāng)前屏幕顯示的消息數(shù)量 */ private int MAX_MSG_NUMBER = 20;
private List<MsgBean> getDataFromDb() {
List<?> dbSize = db.selector(MsgBean.class).where(WhereBuilder.b("id", "=", 400)).findAll();//記得捕獲null指針和DbException異常
//如果數(shù)據(jù)庫比我們顯示的頁數(shù)小,則不偏移,否則,偏移到我們需要顯示的位置
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();是我們實現(xiàn)分頁的關(guān)鍵
.limit是我們定義的分頁大小
.offset偏移量,我們數(shù)據(jù)庫的大小是不變的,如果不定義偏移量,那么我們定義的分頁大小每次只從0取到19.假設(shè)數(shù)據(jù)庫中有21條數(shù)據(jù),那么我們需要從1取到20,而不是0到19,所以偏移1.
然后我們在loadMoreData中
MAX_MSG_NUMBER += MAX_MSG_NUMBER; getDataFromDb();
將大小自加,即完成加載更多的功能,在onLoadData(List<MsgBean> data)中加載數(shù)據(jù)即可.
后面貼上我對xutils數(shù)據(jù)庫操作的封裝,還有很多不完善之處
/**
* 數(shù)據(jù)庫 xutils用法
* @author 青樓愛小生
*/
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;
}
/**
* 增加數(shù)據(jù)
* @param list
* @throws DbException
*/
public void addMsgList(List<MsgBean> list) {
try {
db.saveOrUpdate(list);
} catch (DbException e) {
e.printStackTrace();
LogHelper.e(TAG, e.getMessage());
}
}
/**
* 增加一條數(shù)據(jù)
* @param node
* @throws DbException
*/
public void addMsgToDb(MsgBean node) {
try {
db.saveOrUpdate(node);
} catch (DbException e) {
e.printStackTrace();
LogHelper.e(TAG, e.getMessage());
}
}
/**
* 刪除表中所有數(shù)據(jù)
* @param cls 創(chuàng)建的表的映射
* @throws DbException
*/
public void deleteAll(Class cls) {
try {
db.delete(cls);
} catch (DbException e) {
LogHelper.e(TAG, e.getMessage());
e.printStackTrace();
}
}
/**
* 刪除第一條數(shù)據(jù)
* @param cls
*/
@SuppressWarnings("unchecked")
public void deleteFirst(Class cls){
try {
db.delete(db.findFirst(cls));
} catch (DbException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 查詢表中所有數(shù)據(jù)
* @throws DbException
*/
@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();
}
}
/**
* //添加查詢條件進行查詢
List<ChildInfo> all = db.selector(ChildInfo.class).where("id",">",2).and("id","<",4).findAll();
* @return 搜索指定條件的數(shù)據(jù)
*/
@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();
}
}
/**
* 添加查詢條件進行查詢
* @param cls 表映射
* @param str select語句
* @param format where語句
* @return List<DbModel> DbModel key為數(shù)據(jù)庫列名 value為值
* eg:(Selector.from(Parent.class)
.where("id" ,"<", 54)
.and(WhereBuilder.b("age", ">", 20).or("age", " < ", 30))
.orderBy("id")
.limit(pageSize) .offset(pageSize * pageIndex));
*
*
*
*/
@SuppressWarnings("unchecked")
public Selector<?> findDataBySelector(Class cls,WhereBuilder format){
try {
return db.selector(cls).where(format);
} catch (DbException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
解決Android 10/Android Q手機在后臺無法正常定位問題
這篇文章主要介紹了解決Android 10/Android Q手機在后臺無法正常定位問題,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
Android使用Handler實現(xiàn)View彈性滑動
這篇文章主要介紹了Android使用Handler實現(xiàn)View彈性滑動,介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下2016-08-08
Moshi?完美解決Gson在kotlin中默認(rèn)值空的問題詳解
這篇文章主要為大家介紹了Moshi?完美解決Gson在kotlin中默認(rèn)值空的問題詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03

