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

Android ListView实现下拉加载功能

程序员文章站 2023-12-02 20:23:40
本文实例为大家分享了listview下拉加载展示的具体代码,供大家参考,具体内容如下 1、mylistview.java public class myli...

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

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