Android ListView上拉获取下一页

Posted 漫漫的蜗牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android ListView上拉获取下一页相关的知识,希望对你有一定的参考价值。

    关于ListView上拉刷新的需求很多,实现方式也多种多样。

    一般是简单的通过一个page变量来控制当前请求的页数,然后上拉的时候就发送请求。

    实现出来后,经过测试哥的折腾,发现有诸多细节没有处理好,比如会出现重复数据,反复的上拉导致多次请求等bug。

    后来就决定单独写一个工具类,方便以后需要直接使用。

    

   

  1 public class ListViewScrollHelper<T> {
  2     private static final String TAG = "ListViewScrollHelper";
  3     private static final int LIST_PAGE_SIZE = 15;
  4 
  5     private NextPage nextPage;
  6     private InitAdapter initAdapter;
  7 
  8     private int pageIndex = -1;
  9     private int totalPage;
 10 
 11     private ListView lv_goodsList;
 12     private BaseAdapter goodsAdapter;
 13     private List<T> goodsList = new ArrayList<>();
 14     private Semaphore semaphore = new Semaphore(0);
 15 
 16     public ListViewScrollHelper(ListView lv_goodsList, InitAdapter initAdapter, NextPage nextPage) {
 17         this.initAdapter = initAdapter;
 18         this.lv_goodsList = lv_goodsList;
 19         this.nextPage = nextPage;
 20         initView();
 21     }
 22 
 23     private void initView() {
 24         goodsAdapter = initAdapter.initAdapter(goodsList);
 25         lv_goodsList.setAdapter(goodsAdapter);
 26         lv_goodsList.setOnScrollListener(new AbsListView.OnScrollListener() {
 27             @Override
 28             public void onScrollStateChanged(AbsListView view, int scrollState) {
 29             }
 30 
 31             @Override
 32             public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
 33 
 34                 // 判断是否到底部了
 35                 if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) {
 36                     Log.d(TAG, String.valueOf(pageIndex));
 37                     if (hasNextPage() && canRequestNextPage()) {
 38                         pageIndex++;
 39                         if (nextPage != null)
 40                             nextPage.next();
 41                     } else {
 42                         Log.d(TAG, "列表已经到底部!");
 43                     }
 44                 }
 45             }
 46         });
 47     }
 48 
 49     /**
 50      * 此函数将会作为分页刷新数据的主函数
 51      *     内部将会实现 根据当前页数判断是否重置数据 或者 继续下一页
 52      * 如果重置数据,初始化起始页需要使用函数 resetPageIndex()
 53      *
 54      * @param list
 55      * @param totalSize
 56      */
 57     public void refreshPage(List list, int totalSize) {
 58         if (pageIndex < 0) {
 59             initData(list, totalSize);
 60         } else {
 61             freshList(list);
 62         }
 63     }
 64 
 65     /**
 66      * 如果有多处控制一个listview数据内容(比如:分类,搜索都能控制商品列表展示)
 67      *   ,此时可以使用此函数设置分页信息
 68      *
 69      * @param list
 70      * @param totalSize
 71      */
 72     public void initData(List list, int totalSize) {
 73         pageIndex = 0;
 74         goodsList.clear();
 75 
 76         if (totalSize > LIST_PAGE_SIZE) {
 77             totalPage = totalSize / LIST_PAGE_SIZE;
 78             if (totalSize % LIST_PAGE_SIZE >= 1)
 79                 totalPage++;
 80             Log.d("wbl", "totalPage:" + totalPage);
 81         } else {
 82             totalPage = 1;
 83         }
 84 
 85         freshList(list);
 86     }
 87 
 88     /**
 89      * 设置下一面的数据
 90      *
 91      * @param list
 92      * @param type (此字段废弃)
 93      */
 94     public void nextPage(List list, int type) {
 95         freshList(list);
 96     }
 97 
 98     /**
 99      * 当请求失败时,恢复上到一页
100      */
101     public void restoreLastPage() {
102         if (!canRequestNextPage()) {
103             if (pageIndex > 0) pageIndex--;
104         }
105         semaphore.release();
106     }
107 
108     private boolean hasNextPage() {
109         return pageIndex < totalPage - 1;
110     }
111 
112     public int getPageIndex() {
113         return pageIndex < 0 ? 0 : pageIndex;
114     }
115 
116     public int getPageIndex(boolean hasCategoryChange) {
117         if (hasCategoryChange)
118             pageIndex = 0;
119         return getPageIndex();
120     }
121 
122     /**
123      * 重置分页参数
124      */
125     public void resetPageIndex() {
126         pageIndex = -1;
127         totalPage = 0;
128     }
129 
130     public void setEmptyView(View view) {
131         lv_goodsList.setEmptyView(view);
132     }
133 
134     /**
135      * @param list 传入要显示的list
136      */
137     private void freshList(List list) {
138         if (list != null && list.size() > 0) {
139             goodsList.addAll(list);
140         }
141         goodsAdapter.notifyDataSetChanged();
142         semaphore.release();
143     }
144 
145     private boolean canRequestNextPage() {
146         return semaphore.tryAcquire();
147     }
148 
149     public List<T> getGoodsList() {
150         return goodsList;
151     }
152 
153     public interface NextPage {
154         void next();
155     }
156 
157     public interface InitAdapter<T> {
158         BaseAdapter initAdapter(List<T> list);
159     }
160 }

 

详细使用可以参考这个项目

https://github.com/awenblue/ListViewScroll

 

以上是关于Android ListView上拉获取下一页的主要内容,如果未能解决你的问题,请参考以下文章

在Android中向上滚动ListView时加载页面

android 下拉分页,重复数据问题???

Android PullToRefresh 下拉刷新,上拉很多其它,支持ScrollView,ListView,可方便拓展GridView,WebView等

uniapp 微信小程序实现上拉分页

清新大气的ListView下拉上拉刷新--第三方开源--PullDownListView

使用 Laravel API 进行滚动分页