当前位置: 移动技术网 > 移动技术>移动开发>Android > Android ListView实现下拉加载功能

Android ListView实现下拉加载功能

2019年07月24日  | 移动技术网移动技术  | 我要评论

本文实例为大家分享了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> 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网