Android实现ListView分页自动加载数据的方法

时间:2022-02-21 00:34:15

android应用开发中,采用listview组件来展示数据是很常用的功能,当一个应用要展现很多的数据时,一般情况下都不会把所有的数据一次就展示出来,而是通过分页的形式来展示数据,个人觉得这样会有更好的用户体验。因此,很多应用都是采用分批次加载的形式来获取用户所需的数据。例如:微博客户端可能会在用户滑动至列表底端时自动加载下一页数据,也可能在底部放置一个"查看更多"按钮,用户点击后,加载下一页数据。
下面通过一个demo来展示listview功能如何实现:该demo通过在listview列表的底部添加一个“查看更多...”按钮来加载新闻(模拟新闻客户端)分页数据。同时限定每次加载10条记录,但完全加载完数据后,就把listview列表底部视图“查看更多...”删除。假设加载的数据总数为 38 条记录。先看下该demo工程的程序结构图:

Android实现ListView分页自动加载数据的方法

其中包 com.andyidea.bean中news.java类是新闻实体类,包com.andyidea.listview中paginationlistviewactivity.java类是用来展示listview列表。布局layout中包含三个布局文件,分别为:list_item.xml , loadmore.xml , main.xml 。下面分别贴下源码:
layout中的 list_item.xml源码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<span style="font-size:13px;"><?xml version="1.0" encoding="utf-8"?>
<linearlayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical">
 <textview
   android:id="@+id/newstitle"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"/>
 <textview
   android:id="@+id/newscontent"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"/>
</linearlayout></span>

layout中loadmore.xml源码:

?
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<linearlayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <button 
   android:id="@+id/loadmorebutton"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="查看更多..." /> 
</linearlayout>

layout中main.xml源码:

?
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <listview
    android:id="@+id/lvnews"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"/>
</linearlayou

包 com.andyidea.bean中news.java类源码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.andyidea.bean;
public class news {
   
  private string title;  //标题
  private string content; //内容
   
  public string gettitle() {
    return title;
  }
  public void settitle(string title) {
    this.title = title;
  }
  public string getcontent() {
    return content;
  }
  public void setcontent(string content) {
    this.content = content;
  }
 
}

包com.andyidea.listview中paginationlistviewactivity.java类源码:

?
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
package com.andyidea.listview;
 
import java.util.arraylist;
import java.util.list;
 
import com.andyidea.bean.news;
 
import android.app.activity;
import android.os.bundle;
import android.os.handler;
import android.util.log;
import android.view.view;
import android.view.viewgroup;
import android.widget.abslistview;
import android.widget.abslistview.onscrolllistener;
import android.widget.baseadapter;
import android.widget.button;
import android.widget.listview;
import android.widget.textview;
import android.widget.toast;
 
public class paginationlistviewactivity extends activity implements onscrolllistener {
   
  private listview listview; 
  private int visiblelastindex = 0//最后的可视项索引 
  private int visibleitemcount;    // 当前窗口可见项总数 
  private int datasize = 38;     //模拟数据集的条数
  private paginationadapter adapter; 
  private view loadmoreview; 
  private button loadmorebutton; 
  private handler handler = new handler(); 
   
  /** called when the activity is first created. */
  @override
  public void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.main);
     
    loadmoreview = getlayoutinflater().inflate(r.layout.loadmore, null);
    loadmorebutton = (button)loadmoreview.findviewbyid(r.id.loadmorebutton);
    loadmorebutton.setonclicklistener(new view.onclicklistener() {
       
      @override
      public void onclick(view v) {
        loadmorebutton.settext("正在加载中...");  //设置按钮文字
        handler.postdelayed(new runnable() {
           
          @override
          public void run() {
            loadmoredata();
            adapter.notifydatasetchanged();
            loadmorebutton.settext("查看更多..."); //恢复按钮文字
          }
        },2000);
         
      }
    });
     
    listview = (listview)findviewbyid(r.id.lvnews);
    listview.addfooterview(loadmoreview);  //设置列表底部视图
    initializeadapter();
    listview.setadapter(adapter);
    listview.setonscrolllistener(this);
  }
   
  @override
  public void onscrollstatechanged(abslistview view, int scrollstate) {
    int itemslastindex = adapter.getcount()-1; //数据集最后一项的索引 
    int lastindex = itemslastindex + 1;
    if (scrollstate == onscrolllistener.scroll_state_idle
        && visiblelastindex == lastindex) {
      // 如果是自动加载,可以在这里放置异步加载数据的代码
    }
  }
 
 
  @override
  public void onscroll(abslistview view, int firstvisibleitem,
      int visibleitemcount, int totalitemcount) {
    this.visibleitemcount = visibleitemcount;
    visiblelastindex = firstvisibleitem + visibleitemcount - 1;
     
    log.e("========================= ","========================");
    log.e("firstvisibleitem = ",firstvisibleitem+"");
    log.e("visibleitemcount = ",visibleitemcount+"");
    log.e("totalitemcount = ",totalitemcount+"");
    log.e("========================= ","========================");
     
    //如果所有的记录选项等于数据集的条数,则移除列表底部视图
    if(totalitemcount == datasize+1){
      listview.removefooterview(loadmoreview);
      toast.maketext(this, "数据全部加载完!", toast.length_long).show();
    }
  }
   
  /**
   * 初始化listview的适配器
   */
  private void initializeadapter(){
    list<news> news = new arraylist<news>();
    for(int i=1;i<=10;i++){
      news items = new news();
      items.settitle("title"+i);
      items.setcontent("this is news content"+i);
      news.add(items);
    }
    adapter = new paginationadapter(news);
  }
   
  /**
   * 加载更多数据
   */
  private void loadmoredata(){
    int count = adapter.getcount();
     
    if(count+10 <= datasize){
      for(int i=count+1; i<=count+10; i++){
        news item = new news();
        item.settitle("title"+i);
        item.setcontent("this is news content"+i);
        adapter.addnewsitem(item);
      }
    }else{
      for(int i=count+1; i<=datasize; i++){
        news item = new news();
        item.settitle("title"+i);
        item.setcontent("this is news content"+i);
        adapter.addnewsitem(item);
      }
    }
     
  }
   
   
  class paginationadapter extends baseadapter{
     
    list<news> newsitems;
     
    public paginationadapter(list<news> newsitems){
      this.newsitems = newsitems;
    }
 
    @override
    public int getcount() {
      return newsitems.size();
    }
 
    @override
    public object getitem(int position) {
      return newsitems.get(position);
    }
 
    @override
    public long getitemid(int position) {
      return position;
    }
 
    @override
    public view getview(int position, view view, viewgroup parent) {
      if(view == null){
        view = getlayoutinflater().inflate(r.layout.list_item, null);
      }
       
      //新闻标题
      textview tvtitle = (textview)view.findviewbyid(r.id.newstitle);
      tvtitle.settext(newsitems.get(position).gettitle());
      //新闻内容
      textview tvcontent = (textview)view.findviewbyid(r.id.newscontent);
      tvcontent.settext(newsitems.get(position).getcontent());
       
      return view;
    }
     
    /**
     * 添加数据列表项
     * @param newsitem
     */
    public void addnewsitem(news newsitem){
      newsitems.add(newsitem);
    }
     
  }
 
}

最后,运行程序的结果截图如下:

Android实现ListView分页自动加载数据的方法

通过上面的截图,当我们点击"查看更多..."按钮时,就会加载下10条记录,当加载完所有的记录后,listview的底部视图将会移除。

希望本文所述对大家学习android软件编程有所帮助。