Android开发之ListView列表刷新和加载更多实现方法
程序员文章站
2022-06-10 19:13:08
本文实例讲述了android开发之listview列表刷新和加载更多实现方法。分享给大家供大家参考。具体如下:
上下拉实现刷新和加载更多的listview,如下:...
本文实例讲述了android开发之listview列表刷新和加载更多实现方法。分享给大家供大家参考。具体如下:
上下拉实现刷新和加载更多的listview,如下:
package com.sin.android.ui; import android.content.context; import android.util.attributeset; import android.view.gravity; import android.view.motionevent; import android.view.view; import android.widget.abslistview; import android.widget.abslistview.onscrolllistener; import android.widget.linearlayout; import android.widget.listview; import android.widget.progressbar; import android.widget.textview; /** * 动态刷新和加载数据listview * @author robintang * */ public class dynamiclistview extends listview implements onscrolllistener { /** * 监听器 * 监听控件的刷新或者加载更多事件 * 所有的条目事件都会有一个偏移量,也就是position应该减1才是你适配器中的条目 * @author robintang * */ public interface dynamiclistviewlistener { /** * * @param dynamiclistview * @param isrefresh 为true的时候代表的是刷新,为false的时候代表的是加载更多 * @return true:刷新或者加载更多动作完成,刷新或者加载更多的动画自动消失 false:刷新或者加载更多为完成,需要在数据加载完成之后去调用控件的donerefresh()或者donemore()方法 */ public boolean onrefreshormore(dynamiclistview dynamiclistview, boolean isrefresh); } /** * 状态控件(statusview,列表头上和底端的)的状态枚举 * @author robintang * */ enum refreshstatus { none, normal, willrefresh, refreshing } /** * 状态控件 * @author robintang * */ class statusview extends linearlayout { public int height; public int width; private progressbar progressbar = null; private textview textview = null; private refreshstatus refreshstatus = refreshstatus.none; private string normalstring = "下拉刷新"; private string willrefreshstring = "松开刷新"; private string refreshingstring = "正在刷新"; public statusview(context context, attributeset attrs) { super(context, attrs); initthis(context); } public statusview(context context) { super(context); initthis(context); } private void initthis(context context) { this.setorientation(linearlayout.horizontal); this.setgravity(gravity.center_horizontal | gravity.center_vertical); progressbar = new progressbar(context); progressbar.setlayoutparams(new linearlayout.layoutparams(30, 30)); textview = new textview(context); textview.setpadding(5, 0, 0, 0); this.addview(progressbar); this.addview(textview); int w = view.measurespec.makemeasurespec(0, view.measurespec.unspecified); int h = view.measurespec.makemeasurespec(0, view.measurespec.unspecified); this.measure(w, h); height = this.getmeasuredheight(); width = this.getmeasuredwidth(); this.setrefreshstatus(refreshstatus.normal); } public refreshstatus getrefreshstatus() { return refreshstatus; } public void setrefreshstatus(refreshstatus refreshstatus) { if (this.refreshstatus != refreshstatus) { this.refreshstatus = refreshstatus; if(refreshstatus == refreshstatus.refreshing){ this.progressbar.setvisibility(view.visible); } else{ this.progressbar.setvisibility(view.gone); } refreshstatusstring(); this.invalidate(); } } private void refreshstatusstring() { switch (refreshstatus) { case normal: textview.settext(normalstring); progressbar.setprogress(0); break; case willrefresh: textview.settext(willrefreshstring); break; case refreshing: textview.settext(refreshingstring); break; default: break; } } /** * 设置状态字符串 * @param normalstring 平时的字符串 * @param willrefreshstring 松开后刷新(或加载)的字符串 * @param refreshingstring 正在刷新(或加载)的字符串 */ public void setstatusstrings(string normalstring, string willrefreshstring, string refreshingstring){ this.normalstring = normalstring; this.willrefreshstring = willrefreshstring; this.refreshingstring = refreshingstring; this.refreshstatusstring(); } } private statusview refreshview; private statusview moreview; private int itemflag = -1; private boolean isrecorded = false; private int downy = -1; private final float mintimestorefresh = 1.5f; private final static int item_flag_first = 1; private final static int item_flag_none = 0; private final static int item_flag_last = -1; // 两个监听器 private dynamiclistviewlistener onrefreshlistener; private dynamiclistviewlistener onmorelistener; // 滚动到低端的时候是否自动加载更多 private boolean domorewhenbottom = false; public dynamiclistview(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); initthis(context); } public dynamiclistview(context context, attributeset attrs) { super(context, attrs); initthis(context); } public dynamiclistview(context context) { super(context); initthis(context); } private void initthis(context context) { refreshview = new statusview(context); moreview = new statusview(context); refreshview.setstatusstrings("继续下拉刷新数据...", "松开之后刷新数据...", "正在刷新数据..."); moreview.setstatusstrings("继续上拉加载数据...", "松开之后加载数据...", "正在加载数据..."); this.addheaderview(refreshview, null, false); this.addfooterview(moreview, null, false); this.setonscrolllistener(this); donerefresh(); donemore(); } // 监听器操作 public dynamiclistviewlistener getonrefreshlistener() { return onrefreshlistener; } public void setonrefreshlistener(dynamiclistviewlistener onrefreshlistener) { this.onrefreshlistener = onrefreshlistener; } public dynamiclistviewlistener getonmorelistener() { return onmorelistener; } public void setonmorelistener(dynamiclistviewlistener onmorelistener) { this.onmorelistener = onmorelistener; } // 设置 public boolean isdomorewhenbottom() { return domorewhenbottom; } public void setdomorewhenbottom(boolean domorewhenbottom) { this.domorewhenbottom = domorewhenbottom; } @override public void onscroll(abslistview l, int t, int oldl, int count) { // log("%d %d %d", t, oldl, count); if (t == 0) itemflag = item_flag_first; else if ((t + oldl) == count){ itemflag = item_flag_last; if(domorewhenbottom && onmorelistener != null && moreview.getrefreshstatus() != refreshstatus.refreshing){ domore(); } } else { itemflag = item_flag_none; // isrecorded = false; } } @override public void onscrollstatechanged(abslistview arg0, int arg1) { } @override public boolean ontouchevent(motionevent ev) { switch (ev.getaction()) { case motionevent.action_down: if (isrecorded == false && (itemflag == item_flag_first && onrefreshlistener != null && refreshview.getrefreshstatus() == refreshstatus.normal || itemflag == item_flag_last && onmorelistener != null && moreview.getrefreshstatus() == refreshstatus.normal)) { downy = (int) ev.gety(0); isrecorded = true; // log("按下,记录:%d flag:%d", downy, itemflag); } break; case motionevent.action_up: { isrecorded = false; if (onrefreshlistener != null && refreshview.getrefreshstatus() == refreshstatus.willrefresh) { dorefresh(); } else if (refreshview.getrefreshstatus() == refreshstatus.normal) { refreshview.setpadding(0, -1 * refreshview.height, 0, 0); } if (onmorelistener != null && moreview.getrefreshstatus() == refreshstatus.willrefresh) { domore(); } else if (moreview.getrefreshstatus() == refreshstatus.normal) { moreview.setpadding(0, 0, 0, -1 * moreview.height); } break; } case motionevent.action_move: { if (isrecorded == false && (itemflag == item_flag_first && onrefreshlistener != null && refreshview.getrefreshstatus() == refreshstatus.normal || itemflag == item_flag_last && onmorelistener != null && moreview.getrefreshstatus() == refreshstatus.normal)) { downy = (int) ev.gety(0); isrecorded = true; // log("按下,记录:%d flag:%d", downy, itemflag); } else if (isrecorded) { int nowy = (int) ev.gety(0); int offset = nowy - downy; if (offset > 0 && itemflag == item_flag_first) { // 下拉 setselection(0); if (offset >= (mintimestorefresh * refreshview.height)) { refreshview.setrefreshstatus(refreshstatus.willrefresh); } else { refreshview.setrefreshstatus(refreshstatus.normal); } refreshview.setpadding(0, -1 * (refreshview.height - offset), 0, 0); } else if(itemflag == item_flag_last){ // 上拉 setselection(this.getcount()); if (offset <= -1 * (mintimestorefresh * moreview.height)) { moreview.setrefreshstatus(refreshstatus.willrefresh); } else { moreview.setrefreshstatus(refreshstatus.normal); } moreview.setpadding(0, 0, 0, -1 * (moreview.height + offset)); } // log("位移:%d", offset); } break; } default: break; } return super.ontouchevent(ev); } /** * 开始刷新 */ private void dorefresh(){ // log("开始刷新"); refreshview.setrefreshstatus(refreshstatus.refreshing); refreshview.setpadding(0, 0, 0, 0); if(onrefreshlistener.onrefreshormore(this, true)) donerefresh(); } /** * 开始加载更多 */ private void domore(){ // log("加载更多"); moreview.setrefreshstatus(refreshstatus.refreshing); moreview.setpadding(0, 0, 0, 0); if(onmorelistener.onrefreshormore(this, false)) donemore(); } /** * 刷新完成之后调用,用于取消刷新的动画 */ public void donerefresh() { // log("刷新完成!"); refreshview.setrefreshstatus(refreshstatus.normal); refreshview.setpadding(0, -1 * refreshview.height, 0, 0); } /** * 加载更多完成之后调用,用于取消加载更多的动画 */ public void donemore() { // log("加载完成!"); moreview.setrefreshstatus(refreshstatus.normal); moreview.setpadding(0, 0, 0, -1 * moreview.height); } /** * 获取刷新的状态 * @return 一般 将要刷新 刷新完成 */ public refreshstatus getrefreshstatus(){ return refreshview.getrefreshstatus(); } /** * 获取加载更多的状态 * @return 一般 将要加载 加载完成 */ public refreshstatus getmorestatus(){ return moreview.getrefreshstatus(); } // private void log(object obj) { // log("%s", obj.tostring()); // } // // private void log(string format, object... args) { // log.i("dynamiclistview", string.format(format, args)); // } }
使用例子:
package com.sin.android.ui; import java.util.arraylist; import java.util.date; import android.annotation.suppresslint; import android.app.activity; import android.os.bundle; import android.os.handler; import android.os.message; import android.util.log; import android.view.view; import android.widget.adapterview; import android.widget.adapterview.onitemclicklistener; import android.widget.arrayadapter; import android.widget.toast; import com.sin.android.ui.dynamiclistview.dynamiclistviewlistener; @suppresslint("handlerleak") public class mainactivity extends activity implements dynamiclistviewlistener { dynamiclistview listview; arraylist<string> data; arrayadapter<string> adapter; // 用于刷新控件状态 handler handler = new handler() { @override public void handlemessage(message msg) { if (msg.what == 0) { adapter.notifydatasetchanged(); listview.donerefresh(); toast.maketext(mainactivity.this, "新加载"+msg.arg1+"条数据!", toast.length_long).show(); } else if (msg.what == 1) { adapter.notifydatasetchanged(); listview.donemore(); } else { super.handlemessage(msg); } } }; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); listview = new dynamiclistview(this); setcontentview(listview); data = new arraylist<string>(); for (int i = 1; i < 10; ++i) { data.add("原始数据" + i); } adapter = new arrayadapter<string>(this, android.r.layout.simple_expandable_list_item_1, data); listview.setadapter(adapter); listview.setonitemclicklistener(new onitemclicklistener() { @override public void onitemclick(adapterview<?> arg0, view arg1, int arg2, long arg3) { log.i("",data.get(arg2-1)); } }); listview.setdomorewhenbottom(false); // 滚动到低端的时候不自己加载更多 listview.setonrefreshlistener(this); listview.setonmorelistener(this); } @override public boolean onrefreshormore(dynamiclistview dynamiclistview, boolean isrefresh) { if (isrefresh) { new thread(new runnable() { @override public void run() { // 刷新 arraylist<string> temp = new arraylist<string>(); for (int i = 0; i < 3; ++i) { temp.add(0, new date().tolocalestring()); try { thread.sleep(1000); } catch (interruptedexception e) { e.printstacktrace(); } } synchronized (data) { data.addall(0, temp); } message message = new message(); message.what = 0; message.arg1 = temp.size(); handler.sendmessage(message); } }).start(); } else { new thread(new runnable() { @override public void run() { // 加载更多 arraylist<string> temp = new arraylist<string>(); for (int i = 0; i < 3; ++i) { temp.add(new date().tolocalestring()); try { thread.sleep(1000); } catch (interruptedexception e) { e.printstacktrace(); } } synchronized (data) { data.addall(temp); } handler.sendemptymessage(1); } }).start(); } return false; } }
运行截图如下:
希望本文所述对大家的android程序设计有所帮助。
上一篇: android读取assets文件示例