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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM