欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android开发教程之实现listview下拉刷新和上拉刷新效果

程序员文章站 2023-11-08 14:48:04
复制代码 代码如下:public class pulltoloadlistview extends listview implements onscrolllistener...

复制代码 代码如下:

public class pulltoloadlistview extends listview implements onscrolllistener {

 private static final string tag = pulltoloadlistview.class.getsimplename();

 private static final int state_non = 0;
 private static final int state_pull_to_refresh = 1;
 private static final int state_release_to_refresh = 2;
 private static final int state_refreshing = 3;

 private int state;

 private int firstvisibleitem;
 private int lastvisisibleitem;

 private float prevy = 0;

 private view headerview;
 private view footerview;

 // header widgets
 private progressbar headerprogressbar;
 private imageview headerimagearrow;
 private textview headertext;
 private rotateanimation headerarrowanim;
 private rotateanimation headerarrowreverseanim;
 // footer widgets
 private progressbar footerprogressbar;
 private textview footertext;

 private boolean headerishanding = false;
 private boolean footerishanding = false;

 private int headerheight;
 private int footerheight;

 private resetanimation resetanim;

 private onloadinglistener onloadinglistener;

 private onscrolllistener onscrolllistener;

 public pulltoloadlistview(context context) {
  super(context);
  init(context);
 }

 public pulltoloadlistview(context context, attributeset attrs) {
  super(context, attrs);
  init(context);
 }

 private void init(context context) {
  state = state_non;
  firstvisibleitem = 0;
  lastvisisibleitem = 0;

  layoutinflater inflater = layoutinflater.from(context);
  headerview = inflater.inflate(r.layout.view_pull_header, null);
  footerview = inflater.inflate(r.layout.view_pull_footer, null);

  headerprogressbar = (progressbar) headerview.findviewbyid(r.id.progressbar);
  headerimagearrow = (imageview) headerview.findviewbyid(r.id.arrow);
  headertext = (textview) headerview.findviewbyid(r.id.text);
  headerarrowanim = new rotateanimation(0, -180, animation.relative_to_self, 0.5f, animation.relative_to_self, 0.5f);
  headerarrowanim.setduration(300);
  headerarrowanim.setfillafter(true);
  headerarrowreverseanim = new rotateanimation(-180, 0, animation.relative_to_self, 0.5f, animation.relative_to_self, 0.5f);
  headerarrowreverseanim.setduration(300);
  headerarrowreverseanim.setfillafter(true);

  footerprogressbar = (progressbar) footerview.findviewbyid(r.id.progressbar);
  footertext = (textview) footerview.findviewbyid(r.id.text);

  measureview(headerview);
  measureview(footerview);
  headerheight = headerview.getmeasuredheight();
  footerheight = footerview.getmeasuredheight();
  headerview.setpadding(0, -1 * headerview.getmeasuredheight(), 0, 0);
  footerview.setpadding(0, -1 * footerview.getmeasuredheight(), 0, 0);
  headerview.invalidate();
  footerview.invalidate();
  addheaderview(headerview, null, false);
  addfooterview(footerview, null, false);

  super.setonscrolllistener(this);
 }

 private void measureview(view view) {
  viewgroup.layoutparams lp = view.getlayoutparams();
  if(lp == null) {
   lp = new viewgroup.layoutparams(viewgroup.layoutparams.match_parent, viewgroup.layoutparams.wrap_content);
  }
  int childwidthspec = viewgroup.getchildmeasurespec(0, 0, lp.width);
  int childheightspec;
  if(lp.height > 0) {
   childheightspec = measurespec.makemeasurespec(0, measurespec.exactly);
  } else {
   childheightspec = measurespec.makemeasurespec(0, measurespec.unspecified);
  }
  view.measure(childwidthspec, childheightspec);
 }

 private void resetheader() {
  //  headerview.setpadding(0, -1 * headerheight, 0, 0);
  resetanim = new resetanimation(headerview, headerheight, headerview.getpaddingtop());
  resetanim.start();
 }

 private void resetfooter() {
  resetanim = new resetanimation(footerview, footerheight, footerview.getpaddingtop());
  resetanim.start();
 }

 private void changeheaderviewbystate(int state) {
  if(this.state == state) {
   return ;
  }
  int prevstate = this.state;
  this.state = state;

  switch(state) {
  case state_non:
   headerprogressbar.setvisibility(view.invisible);
   headerimagearrow.setvisibility(view.visible);
   headerimagearrow.clearanimation();
   headertext.settext("pull down to refresh");
   break;
  case state_pull_to_refresh:
   headerprogressbar.setvisibility(view.invisible);
   headerimagearrow.setvisibility(view.visible);
   headertext.settext("pull down to refresh");
   if(prevstate == state_release_to_refresh) {
    headerimagearrow.startanimation(headerarrowreverseanim);
   } else {
    headerimagearrow.clearanimation();
   }
   break;
  case state_release_to_refresh:
   headerprogressbar.setvisibility(view.invisible);
   headerimagearrow.setvisibility(view.visible);
   headerimagearrow.startanimation(headerarrowanim);
   headertext.settext("release to refresh");
   break;
  case state_refreshing:
   headerprogressbar.setvisibility(view.visible);
   headerimagearrow.setvisibility(view.invisible);
   headerimagearrow.clearanimation();
   headertext.settext("refreshing");
   break;
  default:
   break;
  }
 }

 private void changefooterviewbystate(int state) {
  if(this.state == state) {
   return ;
  }
  this.state = state;

  switch(state) {
  case state_non:
   footerprogressbar.setvisibility(view.invisible);
   footertext.settext("pull up to refresh");
   break;
  case state_pull_to_refresh:
   footerprogressbar.setvisibility(view.invisible);
   footertext.settext("pull up to refresh");
   break;
  case state_release_to_refresh:
   footerprogressbar.setvisibility(view.invisible);
   footertext.settext("release to refresh");
   break;
  case state_refreshing:
   footerprogressbar.setvisibility(view.visible);
   footertext.settext("refreshing");
   break;
  default:
   break;
  }
 }

 @override
 public void setonscrolllistener(onscrolllistener l) {
  this.onscrolllistener = l;
 }

 public void setonloadinglistener(onloadinglistener onloadinglistener) {
  this.onloadinglistener = onloadinglistener;
 }

 public void loadcompleted() {
  if(headerishanding) {
   changeheaderviewbystate(state_non);
   resetheader();
   headerishanding = false;
  }
  if(footerishanding) {
   changefooterviewbystate(state_non);
   resetfooter();
   footerishanding = false;
  }
 }

 private void handlemoveheaderevent(motionevent ev) {
  headerishanding = true;
  float tempy = ev.getrawy();
  float vector = tempy - prevy;
  vector /= 2;
  prevy = tempy;
  if(vector > 0) {
   int newpadding = (int) (headerview.getpaddingtop() + vector);
   newpadding = math.min(newpadding, headerheight / 2);
   headerview.setpadding(0, newpadding, 0, 0);
   if(state != state_refreshing) {
    if(newpadding > 0) {
     changeheaderviewbystate(state_release_to_refresh);
    } else {
     changeheaderviewbystate(state_pull_to_refresh);
    }
   }
  } else {
   if(state == state_release_to_refresh || state == state_pull_to_refresh) {
    int newpadding = (int) (headerview.getpaddingtop() + vector);
    newpadding = math.max(newpadding, -1 * headerheight);
    headerview.setpadding(0, newpadding, 0, 0);
    if(newpadding <= -1 * headerheight) {
     changeheaderviewbystate(state_non);
     headerishanding = false;
    } else if(newpadding <= 0) {
     changeheaderviewbystate(state_pull_to_refresh);
    } else {

    }
   }
  }
 }

 private void handlemovefooterevent(motionevent ev) {
  footerishanding = true;
  float tempy = ev.getrawy();
  float vector = tempy - prevy;
  vector /= 2;
  prevy = tempy;
  if(vector < 0) {
   int newpadding = (int) (footerview.getpaddingtop() - vector);
   if(newpadding > 0) {
    newpadding = 0;
   }
   footerview.setpadding(0, newpadding, 0, 0);
   if(state != state_refreshing) {
    if(newpadding < 0) {
     changefooterviewbystate(state_pull_to_refresh);
    } else {
     changefooterviewbystate(state_release_to_refresh);
    }
   }
  } else {
   int newpadding = (int) (footerview.getpaddingtop() - vector);
   newpadding = math.min(newpadding, footerheight);
   footerview.setpadding(0, newpadding, 0, 0);
   if(newpadding <= -1 * footerheight) {
    changefooterviewbystate(state_non);
    footerishanding = false;
   } else if(newpadding < 0) {
    changefooterviewbystate(state_pull_to_refresh);
   }
  }
 }

 @override
 public boolean ontouchevent(motionevent ev) {
  switch(ev.getaction()) {
  case motionevent.action_down:
   prevy = ev.getrawy();
   break;
  case motionevent.action_up:
   if(state == state_release_to_refresh) {
    if(headerishanding) {
     changeheaderviewbystate(state_refreshing);
     if(onloadinglistener != null) {
      onloadinglistener.onloadnew();
     }
    }
    if(footerishanding) {
     changefooterviewbystate(state_refreshing);
     if(onloadinglistener != null) {
      onloadinglistener.onloadmore();
     }
    }
   } else if(state == state_pull_to_refresh) {
    if(headerishanding) {
     changeheaderviewbystate(state_non);
     resetheader();
     headerishanding = false;
    }
    if(footerishanding) {
     changefooterviewbystate(state_non);
     resetfooter();
     footerishanding = false;
    }
   } else if(state == state_non) {
    headerishanding = false;
    footerishanding = false;
   } else {
    // state == state_refreshing
    // ignore
   }
   break;
  case motionevent.action_move:
   if(resetanim == null || !resetanim.run) {

    if(state != state_refreshing) {
     adapter adapter = getadapter();
     if(adapter == null) {
      handlemoveheaderevent(ev);
     } else {
      final int count = adapter.getcount();
      if(count <= 0) {
       handlemoveheaderevent(ev);
      } else {
       float tempy = ev.getrawy();
       float vector = tempy - prevy;
       if(firstvisibleitem == 0 && lastvisisibleitem == count - 1) {
        if(headerishanding) {
         handlemoveheaderevent(ev);
        } else if(footerishanding) {
         handlemovefooterevent(ev);
        } else {
         if(vector > 0) {
          handlemoveheaderevent(ev);
         } else if(vector < 0) {
          handlemovefooterevent(ev);
         } else {
          // ignore vector == 0
         }
        }
       } else if(firstvisibleitem == 0 && vector > 0) {
        handlemoveheaderevent(ev);
       } else if(lastvisisibleitem == count - 1 && vector < 0) {
        handlemovefooterevent(ev);
       } else {
        // ignore
       }
      }
     }
    }
   }
   break;
  default:
   break;
  }
  return super.ontouchevent(ev);
 }

 @override
 public void onscrollstatechanged(abslistview view, int scrollstate) {
  if(onscrolllistener != null) {
   onscrolllistener.onscrollstatechanged(view, scrollstate);
  }
 }

 @override
 public void onscroll(abslistview view, int firstvisibleitem,
   int visibleitemcount, int totalitemcount) {
  this.firstvisibleitem = firstvisibleitem;
  this.lastvisisibleitem = firstvisibleitem + visibleitemcount - 1;
  if(onscrolllistener != null) {
   onscrolllistener.onscroll(view, firstvisibleitem, visibleitemcount, totalitemcount);
  }
 }

 static class resetanimation extends thread {

  static final int duration = 600;

  static final int interval = 5;

  view view;
  int orignalheight;
  int paddingtop;

  boolean run = false;

  resetanimation(view view, int orignalheight, int paddingtop) {
   this.view = view;
   this.orignalheight = orignalheight;
   this.paddingtop = paddingtop;
  }

  public void run() {
   run = true;
   int total = orignalheight * 2 + paddingtop;
   int timetotal = duration / interval;
   int piece = total / timetotal;
   int time = 0;
   final view view = this.view;
   final int paddingtop = this.paddingtop;
   do {
    final int nextpaddingtop = paddingtop - time * piece;
    view.post(new runnable() {
     public void run() {
      view.setpadding(0, nextpaddingtop, 0, 0);
      view.postinvalidate();
     }
    });
    try {
     sleep(interval);
    } catch (interruptedexception e) {
     e.printstacktrace();
    }
    time ++;
   } while(time < timetotal);
   run = false;
  }
 }

 public interface onloadinglistener {

  public void onloadnew();

  public void onloadmore();
 }

}