Android ListView实现下拉加载功能
本文实例为大家分享了listview下拉加载展示的具体代码,供大家参考,具体内容如下
1、mylistview.java
public class mylistview extends listview implements onscrolllistener { private final static int release_to_refresh = 0;// 下拉过程的状态值 private final static int pull_to_refresh = 1; // 从下拉返回到不刷新的状态值 private final static int refreshing = 2;// 正在刷新的状态值 private final static int done = 3; private final static int loading = 4; // 实际的padding的距离与界面上偏移距离的比例 private final static int ratio = 3; private layoutinflater inflater; // listview头部下拉刷新的布局 private linearlayout headerview; private textview lvheadertipstv; private textview lvheaderlastupdatedtv; private imageview lvheaderarrowiv; private progressbar lvheaderprogressbar; // 定义头部下拉刷新的布局的高度 private int headercontentheight; private rotateanimation animation; private rotateanimation reverseanimation; private int starty; private int state; private boolean isback; // 用于保证starty的值在一个完整的touch事件中只被记录一次 private boolean isrecored; private onrefreshlistener refreshlistener; private boolean isrefreshable; public mylistview(context context) { super(context); init(context); } public mylistview(context context, attributeset attrs) { super(context, attrs); init(context); } private void init(context context) { inflater = layoutinflater.from(context); headerview = (linearlayout) inflater.inflate(r.layout.lv_header, null); lvheadertipstv = (textview) headerview .findviewbyid(r.id.lvheadertipstv); lvheaderlastupdatedtv = (textview) headerview .findviewbyid(r.id.lvheaderlastupdatedtv); lvheaderarrowiv = (imageview) headerview .findviewbyid(r.id.lvheaderarrowiv); // 设置下拉刷新图标的最小高度和宽度 lvheaderarrowiv.setminimumwidth(70); lvheaderarrowiv.setminimumheight(50); lvheaderprogressbar = (progressbar) headerview .findviewbyid(r.id.lvheaderprogressbar); measureview(headerview); headercontentheight = headerview.getmeasuredheight(); // 设置内边距,正好距离顶部为一个负的整个布局的高度,正好把头部隐藏 headerview.setpadding(0, -1 * headercontentheight, 0, 0); // 重绘一下 headerview.invalidate(); // 将下拉刷新的布局加入listview的顶部 addheaderview(headerview, null, false); // 设置滚动监听事件 setonscrolllistener(this); // 设置旋转动画事件 animation = new rotateanimation(0, -180, rotateanimation.relative_to_self, 0.5f, rotateanimation.relative_to_self, 0.5f); animation.setinterpolator(new linearinterpolator()); animation.setduration(250); animation.setfillafter(true); reverseanimation = new rotateanimation(-180, 0, rotateanimation.relative_to_self, 0.5f, rotateanimation.relative_to_self, 0.5f); reverseanimation.setinterpolator(new linearinterpolator()); reverseanimation.setduration(200); reverseanimation.setfillafter(true); // 一开始的状态就是下拉刷新完的状态,所以为done state = done; // 是否正在刷新 isrefreshable = false; } @override public void onscrollstatechanged(abslistview view, int scrollstate) { } @override public void onscroll(abslistview view, int firstvisibleitem, int visibleitemcount, int totalitemcount) { if (firstvisibleitem == 0) { isrefreshable = true; } else { isrefreshable = false; } } @override public boolean ontouchevent(motionevent ev) { if (isrefreshable) { switch (ev.getaction()) { case motionevent.action_down: if (!isrecored) { isrecored = true; starty = (int) ev.gety();// 手指按下时记录当前位置 } break; case motionevent.action_up: if (state != refreshing && state != loading) { if (state == pull_to_refresh) { state = done; changeheaderviewbystate(); } if (state == release_to_refresh) { state = refreshing; changeheaderviewbystate(); onlvrefresh(); } } isrecored = false; isback = false; break; case motionevent.action_move: int tempy = (int) ev.gety(); if (!isrecored) { isrecored = true; starty = tempy; } if (state != refreshing && isrecored && state != loading) { // 保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动 // 可以松手去刷新了 if (state == release_to_refresh) { setselection(0); // 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步 if (((tempy - starty) / ratio < headercontentheight)// 由松开刷新状态转变到下拉刷新状态 && (tempy - starty) > 0) { state = pull_to_refresh; changeheaderviewbystate(); } // 一下子推到顶了 else if (tempy - starty <= 0) {// 由松开刷新状态转变到done状态 state = done; changeheaderviewbystate(); } } // 还没有到达显示松开刷新的时候,done或者是pull_to_refresh状态 if (state == pull_to_refresh) { setselection(0); // 下拉到可以进入release_to_refresh的状态 if ((tempy - starty) / ratio >= headercontentheight) {// 由done或者下拉刷新状态转变到松开刷新 state = release_to_refresh; isback = true; changeheaderviewbystate(); } // 上推到顶了 else if (tempy - starty <= 0) {// 由done或者下拉刷新状态转变到done状态 state = done; changeheaderviewbystate(); } } // done状态下 if (state == done) { if (tempy - starty > 0) { state = pull_to_refresh; changeheaderviewbystate(); } } // 更新headview的size if (state == pull_to_refresh) { headerview.setpadding(0, -1 * headercontentheight + (tempy - starty) / ratio, 0, 0); } // 更新headview的paddingtop if (state == release_to_refresh) { headerview.setpadding(0, (tempy - starty) / ratio - headercontentheight, 0, 0); } } break; default: break; } } return super.ontouchevent(ev); } // 当状态改变时候,调用该方法,以更新界面 private void changeheaderviewbystate() { switch (state) { case release_to_refresh: lvheaderarrowiv.setvisibility(view.visible); lvheaderprogressbar.setvisibility(view.gone); lvheadertipstv.setvisibility(view.visible); lvheaderlastupdatedtv.setvisibility(view.visible); lvheaderarrowiv.clearanimation();// 清除动画 lvheaderarrowiv.startanimation(animation);// 开始动画效果 lvheadertipstv.settext("松开刷新"); break; case pull_to_refresh: lvheaderprogressbar.setvisibility(view.gone); lvheadertipstv.setvisibility(view.visible); lvheaderlastupdatedtv.setvisibility(view.visible); lvheaderarrowiv.clearanimation(); lvheaderarrowiv.setvisibility(view.visible); // 是由release_to_refresh状态转变来的 if (isback) { isback = false; lvheaderarrowiv.clearanimation(); lvheaderarrowiv.startanimation(reverseanimation); lvheadertipstv.settext("下拉刷新"); } else { lvheadertipstv.settext("下拉刷新"); } break; case refreshing: headerview.setpadding(0, 0, 0, 0); lvheaderprogressbar.setvisibility(view.visible); lvheaderarrowiv.clearanimation(); lvheaderarrowiv.setvisibility(view.gone); lvheadertipstv.settext("正在刷新..."); lvheaderlastupdatedtv.setvisibility(view.visible); break; case done: headerview.setpadding(0, -1 * headercontentheight, 0, 0); lvheaderprogressbar.setvisibility(view.gone); lvheaderarrowiv.clearanimation(); lvheaderarrowiv.setimageresource(r.drawable.arrow); lvheadertipstv.settext("下拉刷新"); lvheaderlastupdatedtv.setvisibility(view.visible); break; } } // 此方法直接照搬自网络上的一个下拉刷新的demo,此处是“估计”headview的width以及height private void measureview(view child) { viewgroup.layoutparams params = child.getlayoutparams(); if (params == null) { params = new viewgroup.layoutparams( viewgroup.layoutparams.fill_parent, viewgroup.layoutparams.wrap_content); } int childwidthspec = viewgroup.getchildmeasurespec(0, 0 + 0, params.width); int lpheight = params.height; int childheightspec; if (lpheight > 0) { childheightspec = measurespec.makemeasurespec(lpheight, measurespec.exactly); } else { childheightspec = measurespec.makemeasurespec(0, measurespec.unspecified); } child.measure(childwidthspec, childheightspec); } public void setonrefreshlistener(onrefreshlistener refreshlistener) { this.refreshlistener = refreshlistener; isrefreshable = true; } public interface onrefreshlistener { public void onrefresh(); } public void onrefreshcomplete() { state = done; lvheaderlastupdatedtv.settext("最近更新:" + new date().tolocalestring()); changeheaderviewbystate(); } private void onlvrefresh() { if (refreshlistener != null) { refreshlistener.onrefresh(); } } public void setadapter(lvadapter adapter) { lvheaderlastupdatedtv.settext("最近更新:" + new date().tolocalestring()); super.setadapter(adapter); } }
2、mainactivity.java
public class mainactivity extends activity { private list<string> list; private mylistview lv; private lvadapter adapter; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); lv = (mylistview) findviewbyid(r.id.lv); list = new arraylist<string>(); list.add("loonggg"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); list.add("我们都是开发者"); adapter = new lvadapter(list, this); lv.setadapter(adapter); lv.setonrefreshlistener(new onrefreshlistener() { @override public void onrefresh() { new asynctask<void, void, void>() { protected void doinbackground(void... params) { try { thread.sleep(1000); } catch (exception e) { e.printstacktrace(); } list.add("刷新后添加的内容"); return null; } @override protected void onpostexecute(void result) { adapter.notifydatasetchanged(); lv.onrefreshcomplete(); } }.execute(null, null, null); } }); } }
3、lvadapter
public class lvadapter extends baseadapter {
private list<string> list;
private context context;
public lvadapter(list<string> list, context context) {
this.list = list;
this.context = context;
}
@override
public int getcount() {
return list.size();
}
@override
public object getitem(int position) {
return list.get(position);
}
@override
public long getitemid(int position) {
return position;
}
@override
public view getview(int position, view convertview, viewgroup parent) {
textview tv = new textview(context.getapplicationcontext());
tv.settext(list.get(position));
return tv;
}
}
4、lv_header.xml
[html] view plain copy
<linearlayout xmlns:android=""
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#000000" >
<!-- 内容 -->
<relativelayout
android:id="@+id/head_contentlayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingleft="30dp" >
<!-- 箭头图像、进度条 -->
<framelayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignparentleft="true"
android:layout_centervertical="true" >
<!-- 箭头 -->
<imageview
android:id="@+id/lvheaderarrowiv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/arrow" />
<!-- 进度条 -->
<progressbar
android:id="@+id/lvheaderprogressbar"
style="?android:attr/progressbarstylesmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</framelayout>
<!-- 提示、最近更新 -->
<linearlayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerhorizontal="true"
android:gravity="center_horizontal"
android:orientation="vertical" >
<!-- 提示 -->
<textview
android:id="@+id/lvheadertipstv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下拉刷新"
android:textcolor="#fff"
android:textsize="20sp" />
<!-- 最近更新 -->
<textview
android:id="@+id/lvheaderlastupdatedtv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="上次更新"
android:textcolor="#333"
android:textsize="10sp" />
</linearlayout>
</relativelayout>
</linearlayout>
5、main.xml
[html] view plain copy
<linearlayout xmlns:android=""
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
android:orientation="vertical" >
<net.loonggg.listview.mylistview
android:id="@+id/lv"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</linearlayout>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。