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

时间:2021-07-29 13:58:46

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
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));
// }
}

使用例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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程序设计有所帮助。