首页 > 代码库 > Android ListView上拉获取下一页

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 传入要显示的list136      */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上拉获取下一页