android编程之下拉刷新实现方法分析
程序员文章站
2023-11-30 22:05:10
本文实例讲述了android编程之下拉刷新实现方法。分享给大家供大家参考,具体如下:
现在android应用里面下拉刷新比较多 ,今天自己研究一下相关的资料
p...
本文实例讲述了android编程之下拉刷新实现方法。分享给大家供大家参考,具体如下:
现在android应用里面下拉刷新比较多 ,今天自己研究一下相关的资料
public class mylistview extends listview implements onscrolllistener { private static final string tag = "listview"; 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; private linearlayout headview; private textview tipstextview; private textview lastupdatedtextview; private imageview arrowimageview; private progressbar progressbar; private rotateanimation animation; private rotateanimation reverseanimation; // 用于保证starty的值在一个完整的touch事件中只被记录一次 private boolean isrecored; private int headcontentwidth; private int headcontentheight; private int starty; private int firstitemindex; private int state; private boolean isback; 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) { setcachecolorhint(context.getresources().getcolor(r.color.transparent)); inflater = layoutinflater.from(context); headview = (linearlayout) inflater.inflate(r.layout.head, null); arrowimageview = (imageview) headview .findviewbyid(r.id.head_arrowimageview); arrowimageview.setminimumwidth(70); arrowimageview.setminimumheight(50); progressbar = (progressbar) headview .findviewbyid(r.id.head_progressbar); tipstextview = (textview) headview.findviewbyid(r.id.head_tipstextview); lastupdatedtextview = (textview) headview .findviewbyid(r.id.head_lastupdatedtextview); measureview(headview); headcontentheight = headview.getmeasuredheight(); headcontentwidth = headview.getmeasuredwidth(); headview.setpadding(0, -1 * headcontentheight, 0, 0); headview.invalidate(); log.v("size", "width:" + headcontentwidth + " height:" + headcontentheight); addheaderview(headview, 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); state = done; isrefreshable = false; } public void onscroll(abslistview arg0, int firstvisiableitem, int arg2, int arg3) { firstitemindex = firstvisiableitem; } public void onscrollstatechanged(abslistview arg0, int arg1) { } public boolean ontouchevent(motionevent event) { if (isrefreshable) { switch (event.getaction()) { case motionevent.action_down: if (firstitemindex == 0 && !isrecored) { isrecored = true; starty = (int) event.gety(); log.v(tag, "在down时候记录当前位置‘"); } break; case motionevent.action_up: if (state != refreshing && state != loading) { if (state == done) { // 什么都不做 } if (state == pull_to_refresh) { state = done; changeheaderviewbystate(); log.v(tag, "由下拉刷新状态,到done状态"); } if (state == release_to_refresh) { state = refreshing; changeheaderviewbystate(); onrefresh(); log.v(tag, "由松开刷新状态,到done状态"); } } isrecored = false; isback = false; break; case motionevent.action_move: int tempy = (int) event.gety(); if (!isrecored && firstitemindex == 0) { log.v(tag, "在move时候记录下位置"); isrecored = true; starty = tempy; } if (state != refreshing && isrecored && state != loading) { // 保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动 // 可以松手去刷新了 if (state == release_to_refresh) { setselection(0); // 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步 if (((tempy - starty) / ratio < headcontentheight) && (tempy - starty) > 0) { state = pull_to_refresh; changeheaderviewbystate(); log.v(tag, "由松开刷新状态转变到下拉刷新状态"); } // 一下子推到顶了 else if (tempy - starty <= 0) { state = done; changeheaderviewbystate(); log.v(tag, "由松开刷新状态转变到done状态"); } // 往下拉了,或者还没有上推到屏幕顶部掩盖head的地步 else { // 不用进行特别的操作,只用更新paddingtop的值就行了 } } // 还没有到达显示松开刷新的时候,done或者是pull_to_refresh状态 if (state == pull_to_refresh) { setselection(0); // 下拉到可以进入release_to_refresh的状态 if ((tempy - starty) / ratio >= headcontentheight) { state = release_to_refresh; isback = true; changeheaderviewbystate(); log.v(tag, "由done或者下拉刷新状态转变到松开刷新"); } // 上推到顶了 else if (tempy - starty <= 0) { state = done; changeheaderviewbystate(); log.v(tag, "由done或者下拉刷新状态转变到done状态"); } } // done状态下 if (state == done) { if (tempy - starty > 0) { state = pull_to_refresh; changeheaderviewbystate(); } } // 更新headview的size if (state == pull_to_refresh) { headview.setpadding(0, -1 * headcontentheight + (tempy - starty) / ratio, 0, 0); } // 更新headview的paddingtop if (state == release_to_refresh) { headview.setpadding(0, (tempy - starty) / ratio - headcontentheight, 0, 0); } } break; } } return super.ontouchevent(event); } // 当状态改变时候,调用该方法,以更新界面 private void changeheaderviewbystate() { switch (state) { case release_to_refresh: arrowimageview.setvisibility(view.visible); progressbar.setvisibility(view.gone); tipstextview.setvisibility(view.visible); lastupdatedtextview.setvisibility(view.visible); arrowimageview.clearanimation(); arrowimageview.startanimation(animation); tipstextview.settext("松开刷新"); log.v(tag, "当前状态,松开刷新"); break; case pull_to_refresh: progressbar.setvisibility(view.gone); tipstextview.setvisibility(view.visible); lastupdatedtextview.setvisibility(view.visible); arrowimageview.clearanimation(); arrowimageview.setvisibility(view.visible); // 是由release_to_refresh状态转变来的 if (isback) { isback = false; arrowimageview.clearanimation(); arrowimageview.startanimation(reverseanimation); tipstextview.settext("下拉刷新"); } else { tipstextview.settext("下拉刷新"); } log.v(tag, "当前状态,下拉刷新"); break; case refreshing: headview.setpadding(0, 0, 0, 0); progressbar.setvisibility(view.visible); arrowimageview.clearanimation(); arrowimageview.setvisibility(view.gone); tipstextview.settext("正在刷新..."); lastupdatedtextview.setvisibility(view.visible); log.v(tag, "当前状态,正在刷新..."); break; case done: headview.setpadding(0, -1 * headcontentheight, 0, 0); progressbar.setvisibility(view.gone); arrowimageview.clearanimation(); arrowimageview.setimageresource(r.drawable.arrow); tipstextview.settext("下拉刷新"); lastupdatedtextview.setvisibility(view.visible); log.v(tag, "当前状态,done"); break; } } public void setonrefreshlistener(onrefreshlistener refreshlistener) { this.refreshlistener = refreshlistener; isrefreshable = true; } public interface onrefreshlistener { public void onrefresh(); } public void onrefreshcomplete() { state = done; lastupdatedtextview.settext("最近更新:" + new date().tolocalestring()); changeheaderviewbystate(); } private void onrefresh() { if (refreshlistener != null) { refreshlistener.onrefresh(); } } // 此方法直接照搬自网络上的一个下拉刷新的demo,此处是“估计”headview的width以及height private void measureview(view child) { viewgroup.layoutparams p = child.getlayoutparams(); if (p == null) { p = new viewgroup.layoutparams(viewgroup.layoutparams.fill_parent, viewgroup.layoutparams.wrap_content); } int childwidthspec = viewgroup.getchildmeasurespec(0, 0 + 0, p.width); int lpheight = p.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 setadapter(baseadapter adapter) { lastupdatedtextview.settext("最近更新:" + new date().tolocalestring()); super.setadapter(adapter); } }
希望本文所述对大家android程序设计有所帮助。