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

Android开发之ListView列表刷新和加载更多实现方法

程序员文章站 2023-11-08 14:30:28
本文实例讲述了android开发之listview列表刷新和加载更多实现方法。分享给大家供大家参考。具体如下: 上下拉实现刷新和加载更多的listview,如下:...

本文实例讲述了android开发之listview列表刷新和加载更多实现方法。分享给大家供大家参考。具体如下:

上下拉实现刷新和加载更多的listview,如下:

package com.sin.android.ui; 
import android.content.context; 
import android.util.attributeset; 
import android.view.gravity; 
import android.view.motionevent; 
import android.view.view; 
import android.widget.abslistview; 
import android.widget.abslistview.onscrolllistener; 
import android.widget.linearlayout; 
import android.widget.listview; 
import android.widget.progressbar; 
import android.widget.textview; 
/** 
 * 动态刷新和加载数据listview 
 * @author robintang 
 * 
 */ 
public class dynamiclistview extends listview implements onscrolllistener { 
  /** 
   * 监听器 
   * 监听控件的刷新或者加载更多事件 
   * 所有的条目事件都会有一个偏移量,也就是position应该减1才是你适配器中的条目 
   * @author robintang 
   * 
   */ 
  public interface dynamiclistviewlistener { 
    /** 
     * 
     * @param dynamiclistview 
     * @param isrefresh 为true的时候代表的是刷新,为false的时候代表的是加载更多 
     * @return true:刷新或者加载更多动作完成,刷新或者加载更多的动画自动消失 false:刷新或者加载更多为完成,需要在数据加载完成之后去调用控件的donerefresh()或者donemore()方法 
     */ 
    public boolean onrefreshormore(dynamiclistview dynamiclistview, boolean isrefresh); 
  } 
  /** 
   * 状态控件(statusview,列表头上和底端的)的状态枚举 
   * @author robintang 
   * 
   */ 
  enum refreshstatus { 
    none, normal, willrefresh, refreshing 
  } 
  /** 
   * 状态控件 
   * @author robintang 
   * 
   */ 
  class statusview extends linearlayout { 
    public int height; 
    public int width; 
    private progressbar progressbar = null; 
    private textview textview = null; 
    private refreshstatus refreshstatus = refreshstatus.none; 
    private string normalstring = "下拉刷新"; 
    private string willrefreshstring = "松开刷新"; 
    private string refreshingstring = "正在刷新"; 
    public statusview(context context, attributeset attrs) { 
      super(context, attrs); 
      initthis(context); 
    } 
    public statusview(context context) { 
      super(context); 
      initthis(context); 
    } 
    private void initthis(context context) { 
      this.setorientation(linearlayout.horizontal); 
      this.setgravity(gravity.center_horizontal | gravity.center_vertical); 
      progressbar = new progressbar(context); 
      progressbar.setlayoutparams(new linearlayout.layoutparams(30, 30)); 
      textview = new textview(context); 
      textview.setpadding(5, 0, 0, 0); 
      this.addview(progressbar); 
      this.addview(textview); 
      int w = view.measurespec.makemeasurespec(0, view.measurespec.unspecified); 
      int h = view.measurespec.makemeasurespec(0, view.measurespec.unspecified); 
      this.measure(w, h); 
      height = this.getmeasuredheight(); 
      width = this.getmeasuredwidth(); 
      this.setrefreshstatus(refreshstatus.normal); 
    } 
    public refreshstatus getrefreshstatus() { 
      return refreshstatus; 
    } 
    public void setrefreshstatus(refreshstatus refreshstatus) { 
      if (this.refreshstatus != refreshstatus) { 
        this.refreshstatus = refreshstatus; 
        if(refreshstatus == refreshstatus.refreshing){ 
          this.progressbar.setvisibility(view.visible); 
        } 
        else{ 
          this.progressbar.setvisibility(view.gone); 
        } 
        refreshstatusstring(); 
        this.invalidate(); 
      } 
    } 
    private void refreshstatusstring() { 
      switch (refreshstatus) { 
      case normal: 
        textview.settext(normalstring); 
        progressbar.setprogress(0); 
        break; 
      case willrefresh: 
        textview.settext(willrefreshstring); 
        break; 
      case refreshing: 
        textview.settext(refreshingstring); 
        break; 
      default: 
        break; 
      } 
    } 
    /** 
     * 设置状态字符串 
     * @param normalstring 平时的字符串 
     * @param willrefreshstring 松开后刷新(或加载)的字符串 
     * @param refreshingstring 正在刷新(或加载)的字符串 
     */ 
    public void setstatusstrings(string normalstring, string willrefreshstring, string refreshingstring){ 
      this.normalstring = normalstring; 
      this.willrefreshstring = willrefreshstring; 
      this.refreshingstring = refreshingstring; 
      this.refreshstatusstring(); 
    } 
  } 
  private statusview refreshview; 
  private statusview moreview; 
  private int itemflag = -1; 
  private boolean isrecorded = false; 
  private int downy = -1; 
  private final float mintimestorefresh = 1.5f; 
  private final static int item_flag_first = 1; 
  private final static int item_flag_none = 0; 
  private final static int item_flag_last = -1; 
  // 两个监听器 
  private dynamiclistviewlistener onrefreshlistener; 
  private dynamiclistviewlistener onmorelistener; 
  // 滚动到低端的时候是否自动加载更多 
  private boolean domorewhenbottom = false; 
  public dynamiclistview(context context, attributeset attrs, int defstyle) { 
    super(context, attrs, defstyle); 
    initthis(context); 
  } 
  public dynamiclistview(context context, attributeset attrs) { 
    super(context, attrs); 
    initthis(context); 
  } 
  public dynamiclistview(context context) { 
    super(context); 
    initthis(context); 
  } 
  private void initthis(context context) { 
    refreshview = new statusview(context); 
    moreview = new statusview(context); 
    refreshview.setstatusstrings("继续下拉刷新数据...", "松开之后刷新数据...", "正在刷新数据..."); 
    moreview.setstatusstrings("继续上拉加载数据...", "松开之后加载数据...", "正在加载数据..."); 
    this.addheaderview(refreshview, null, false); 
    this.addfooterview(moreview, null, false); 
    this.setonscrolllistener(this); 
    donerefresh(); 
    donemore(); 
  } 
  // 监听器操作 
  public dynamiclistviewlistener getonrefreshlistener() { 
    return onrefreshlistener; 
  } 
  public void setonrefreshlistener(dynamiclistviewlistener onrefreshlistener) { 
    this.onrefreshlistener = onrefreshlistener; 
  } 
  public dynamiclistviewlistener getonmorelistener() { 
    return onmorelistener; 
  } 
  public void setonmorelistener(dynamiclistviewlistener onmorelistener) { 
    this.onmorelistener = onmorelistener; 
  } 
  // 设置 
  public boolean isdomorewhenbottom() { 
    return domorewhenbottom; 
  } 
  public void setdomorewhenbottom(boolean domorewhenbottom) { 
    this.domorewhenbottom = domorewhenbottom; 
  } 
  @override 
  public void onscroll(abslistview l, int t, int oldl, int count) { 
    // log("%d %d %d", t, oldl, count); 
    if (t == 0) 
      itemflag = item_flag_first; 
    else if ((t + oldl) == count){ 
      itemflag = item_flag_last; 
      if(domorewhenbottom && onmorelistener != null && moreview.getrefreshstatus() != refreshstatus.refreshing){ 
          domore(); 
      } 
    } 
    else { 
      itemflag = item_flag_none; 
//     isrecorded = false; 
    } 
  } 
  @override 
  public void onscrollstatechanged(abslistview arg0, int arg1) { 
  } 
  @override 
  public boolean ontouchevent(motionevent ev) { 
    switch (ev.getaction()) { 
    case motionevent.action_down: 
      if (isrecorded == false && (itemflag == item_flag_first && onrefreshlistener != null && refreshview.getrefreshstatus() == refreshstatus.normal || itemflag == item_flag_last && onmorelistener != null && moreview.getrefreshstatus() == refreshstatus.normal)) { 
        downy = (int) ev.gety(0); 
        isrecorded = true; 
//       log("按下,记录:%d flag:%d", downy, itemflag); 
      } 
      break; 
    case motionevent.action_up: { 
      isrecorded = false; 
      if (onrefreshlistener != null && refreshview.getrefreshstatus() == refreshstatus.willrefresh) { 
        dorefresh(); 
      } else if (refreshview.getrefreshstatus() == refreshstatus.normal) { 
        refreshview.setpadding(0, -1 * refreshview.height, 0, 0); 
      } 
      if (onmorelistener != null && moreview.getrefreshstatus() == refreshstatus.willrefresh) { 
        domore(); 
      } else if (moreview.getrefreshstatus() == refreshstatus.normal) { 
        moreview.setpadding(0, 0, 0, -1 * moreview.height); 
      } 
      break; 
    } 
    case motionevent.action_move: { 
      if (isrecorded == false && (itemflag == item_flag_first && onrefreshlistener != null && refreshview.getrefreshstatus() == refreshstatus.normal ||  
          itemflag == item_flag_last && onmorelistener != null && moreview.getrefreshstatus() == refreshstatus.normal)) { 
        downy = (int) ev.gety(0); 
        isrecorded = true; 
//       log("按下,记录:%d flag:%d", downy, itemflag); 
      } else if (isrecorded) { 
        int nowy = (int) ev.gety(0); 
        int offset = nowy - downy; 
        if (offset > 0 && itemflag == item_flag_first) { 
          // 下拉 
          setselection(0); 
          if (offset >= (mintimestorefresh * refreshview.height)) { 
            refreshview.setrefreshstatus(refreshstatus.willrefresh); 
          } else { 
            refreshview.setrefreshstatus(refreshstatus.normal); 
          } 
          refreshview.setpadding(0, -1 * (refreshview.height - offset), 0, 0); 
        } else if(itemflag == item_flag_last){ 
          // 上拉 
          setselection(this.getcount()); 
          if (offset <= -1 * (mintimestorefresh * moreview.height)) { 
            moreview.setrefreshstatus(refreshstatus.willrefresh); 
          } else { 
            moreview.setrefreshstatus(refreshstatus.normal);
          } 
          moreview.setpadding(0, 0, 0, -1 * (moreview.height + offset));
        } 
//       log("位移:%d", offset); 
      } 
      break; 
    } 
    default: 
      break; 
    } 
    return super.ontouchevent(ev); 
  } 
  /** 
   * 开始刷新 
   */ 
  private void dorefresh(){ 
//   log("开始刷新"); 
    refreshview.setrefreshstatus(refreshstatus.refreshing); 
    refreshview.setpadding(0, 0, 0, 0); 
    if(onrefreshlistener.onrefreshormore(this, true)) 
      donerefresh(); 
  } 
  /** 
   * 开始加载更多 
   */ 
  private void domore(){ 
//   log("加载更多"); 
    moreview.setrefreshstatus(refreshstatus.refreshing); 
    moreview.setpadding(0, 0, 0, 0); 
    if(onmorelistener.onrefreshormore(this, false)) 
      donemore(); 
  } 
  /** 
   * 刷新完成之后调用,用于取消刷新的动画 
   */ 
  public void donerefresh() { 
//   log("刷新完成!"); 
    refreshview.setrefreshstatus(refreshstatus.normal); 
    refreshview.setpadding(0, -1 * refreshview.height, 0, 0); 
  } 
  /** 
   * 加载更多完成之后调用,用于取消加载更多的动画 
   */ 
  public void donemore() { 
//   log("加载完成!"); 
    moreview.setrefreshstatus(refreshstatus.normal); 
    moreview.setpadding(0, 0, 0, -1 * moreview.height); 
  } 
  /** 
   * 获取刷新的状态 
   * @return 一般 将要刷新 刷新完成 
   */ 
  public refreshstatus getrefreshstatus(){ 
    return refreshview.getrefreshstatus(); 
  } 
  /** 
   * 获取加载更多的状态 
   * @return 一般 将要加载 加载完成 
   */ 
  public refreshstatus getmorestatus(){ 
    return moreview.getrefreshstatus(); 
  } 
// private void log(object obj) { 
//   log("%s", obj.tostring()); 
// } 
// 
// private void log(string format, object... args) { 
//   log.i("dynamiclistview", string.format(format, args)); 
// } 
} 

使用例子:

package com.sin.android.ui; 
import java.util.arraylist; 
import java.util.date; 
import android.annotation.suppresslint; 
import android.app.activity; 
import android.os.bundle; 
import android.os.handler; 
import android.os.message; 
import android.util.log; 
import android.view.view; 
import android.widget.adapterview; 
import android.widget.adapterview.onitemclicklistener; 
import android.widget.arrayadapter; 
import android.widget.toast; 
import com.sin.android.ui.dynamiclistview.dynamiclistviewlistener; 
@suppresslint("handlerleak") 
public class mainactivity extends activity implements dynamiclistviewlistener { 
  dynamiclistview listview; 
  arraylist<string> data; 
  arrayadapter<string> adapter; 
  // 用于刷新控件状态 
  handler handler = new handler() { 
    @override 
    public void handlemessage(message msg) { 
      if (msg.what == 0) { 
        adapter.notifydatasetchanged(); 
        listview.donerefresh(); 
        toast.maketext(mainactivity.this, "新加载"+msg.arg1+"条数据!", toast.length_long).show(); 
      } else if (msg.what == 1) { 
        adapter.notifydatasetchanged(); 
        listview.donemore(); 
      } else { 
        super.handlemessage(msg); 
      } 
    } 
  }; 
  @override 
  protected void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    listview = new dynamiclistview(this); 
    setcontentview(listview); 
    data = new arraylist<string>(); 
    for (int i = 1; i < 10; ++i) { 
      data.add("原始数据" + i); 
    } 
    adapter = new arrayadapter<string>(this, android.r.layout.simple_expandable_list_item_1, data); 
    listview.setadapter(adapter); 
    listview.setonitemclicklistener(new onitemclicklistener() { 
      @override 
      public void onitemclick(adapterview<?> arg0, view arg1, int arg2, long arg3) { 
        log.i("",data.get(arg2-1)); 
      } 
    }); 
    listview.setdomorewhenbottom(false);  // 滚动到低端的时候不自己加载更多 
    listview.setonrefreshlistener(this); 
    listview.setonmorelistener(this); 
  } 
  @override 
  public boolean onrefreshormore(dynamiclistview dynamiclistview, boolean isrefresh) { 
    if (isrefresh) { 
      new thread(new runnable() { 
        @override 
        public void run() { 
          // 刷新 
          arraylist<string> temp = new arraylist<string>(); 
          for (int i = 0; i < 3; ++i) { 
            temp.add(0, new date().tolocalestring()); 
            try { 
              thread.sleep(1000); 
            } catch (interruptedexception e) { 
              e.printstacktrace(); 
            } 
          } 
          synchronized (data) { 
            data.addall(0, temp); 
          } 
          message message = new message(); 
          message.what = 0; 
          message.arg1 = temp.size(); 
          handler.sendmessage(message); 
        } 
      }).start(); 
    } else { 
      new thread(new runnable() { 
        @override 
        public void run() { 
          // 加载更多 
          arraylist<string> temp = new arraylist<string>(); 
          for (int i = 0; i < 3; ++i) { 
            temp.add(new date().tolocalestring()); 
            try { 
              thread.sleep(1000); 
            } catch (interruptedexception e) { 
              e.printstacktrace(); 
            } 
          } 
          synchronized (data) { 
            data.addall(temp); 
          } 
          handler.sendemptymessage(1); 
        } 
      }).start(); 
    } 
    return false; 
  } 
} 

运行截图如下:

Android开发之ListView列表刷新和加载更多实现方法

Android开发之ListView列表刷新和加载更多实现方法

Android开发之ListView列表刷新和加载更多实现方法

Android开发之ListView列表刷新和加载更多实现方法

希望本文所述对大家的android程序设计有所帮助。