国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android代碼實現AdapterViews和RecyclerView無限滾動

2019-12-12 06:02:29
字體:
來源:轉載
供稿:網友

應用的一個共同的特點就是當用戶歡動時自動加載更多的內容,這是通過用戶滑動觸發一定的閾值時發送數據請求實現的。
相同的是:信息實現滑動的效果需要定義在列表中最后一個可見項,和某些類型的閾值以便于開始在最后一項到達之前開始抓取數據,實現無限的滾動。
實現無限滾動的現象的重要之處就在于在用戶滑動到最低端之前就行數據的獲取,所以需要加上一個閾值來幫助實現獲取數據的預期。

使用ListView和GridView實現

每個AdapterView 例如ListView 和GridView 當用戶開始進行滾動操作時候都會觸發OnScrollListener .使用這個系統我們就可以定義一個基本的EndlessScrollListener ,通過創造繼承OnScrollListener 的類來支持大多數情況下的使用。

package com.codepath.customadapter;import android.widget.AbsListView;/** * Created by Administrator on 2016/7/11. */public abstract class EndlessScrollListener implements AbsListView.OnScrollListener { //在你滑動項下最少為多少時開始加載數據 private int visibleThreshold = 5; //已經加載數據的當前頁碼 private int currentPage = 0; //上一次加載數據后數據庫的數據量 private int previousTotalItemCount = 0; //我們是否在等待最后一組數據的加載 private boolean loading = true; //設置開始頁的下標 private int startingPageIndex = 0; public EndlessScrollListener() { } public EndlessScrollListener(int visibleThreshold) {  this.visibleThreshold = visibleThreshold; } public EndlessScrollListener(int visibleThreshold, int startingPageIndex) {  this.visibleThreshold = visibleThreshold;  this.startingPageIndex = startingPageIndex; } //這個方法可能會在滑動調用很多次,所以在設計時要保持謹慎 //我們需要一些有用的參數來幫助我們,當我們需要加載更多數據的時候 //但是我們首先要檢查是否我們在等待先前的加載結束//onScroll()當列表或網格視圖被滾動后將會調用,參數一:報告狀態的視圖參數二:第一個可以看見的項的下標,參數三:可見項的數量參數四:listAdapter中所有的項數 @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {  //如果總項數為0,而且先前沒有項,那么這個列表是無效的應該被設定為初始狀態  if (totalItemCount < previousTotalItemCount) {   this.currentPage = this.startingPageIndex;   this.previousTotalItemCount = totalItemCount;   if (totalItemCount == 0) {this.loading = true;}  }  //如果仍在加載中我們可以檢查一下數據集合是否改變了,如果改變的話那就是已經完成了loading需要更新當前  //頁數和數據總量  if (loading && (totalItemCount > previousTotalItemCount)) {   loading = false;   previousTotalItemCount = totalItemCount;   currentPage++;  }  //如果當前沒有加載,我們需要檢查當前是否達到了閾值,如果是的話我們需要  //加載更多的數據,執行onLoadMore  if (!loading && (firstVisibleItem + visibleItemCount + visibleThreshold) >= totalItemCount) {   loading = onLoadMore(currentPage + 1, totalItemCount);  } } //定義實際加載數據的過程,如果數據加載完成返回false,如果正在加載返回true; public abstract boolean onLoadMore(int page, int totalItemCount); @Override public void onScrollStateChanged(AbsListView view, int scrollState) {  //不采取動作 }}

要注意的是這是一個抽象的類,為了要使用這些,必須繼承這個基本的類并且實現onLoadMore()方法實際的獲取數據, 我們在一個活動中定義一個匿名的類來繼承EndlessScrollListener然后將其連接AdapterView上

public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstance) {  //向平常一樣   ListView lvItems = (ListView) findViewById(R.id.lvItens);   //將監聽器綁定到上面    lvItems.setOnScrollListener(new EndlessScrollListener() {   @Override   public boolean onLoadMore(int page, int totalItemsCount) {    // 當新數據需要綁定到列表上的時候觸發    // 加載數據需要的代碼Add whatever code is needed to append new items to your AdapterView    customLoadMoreDataFromApi(page);     // or customLoadMoreDataFromApi(totalItemsCount);     return true; //數據加載中為true,不然為false; ONLY if more data is actually being loaded; false otherwise.   }  }); } //加載更多的數據 public void customLoadMoreDataFromApi(int offset) {  //這個方法通常會發起一些網絡請求,然后向適配器添加更多的數據  //將偏移量數據作為參數附在請求里來獲得一個數據的分頁  //解析API返回的值并且獲得新的對象構建適配器 }}

現在當用戶滑動并且觸發閾值時會自動觸發onloadMore() 方法,而且監聽器給予了對于頁數和數據總量的訪問權限。

實現RecyclerView的無限滑動

我們可以使用相同的方法來定義一個接口EndlessRecyclerViewScrollListener 然后定義一個onLoadMore() 的方法來進行實現。由于LayoutManager負責項的生成和滑動的管理,我們需要一個LayoutManage的實例來收集必要的信息。
實現必要的分頁需要這樣的步驟:
1).直接復制EndlessRecyclerViewScrollListener.java
2).調用addOnScrollListener(...) 在RecyclerView 中來實現無限的分頁,傳遞EndlessRecyclerViewScrollListener的實例來實現onLoadMore 方法來決定什么時候來加載新的數據
3).在onLoadMore 方法中通過發送網絡請求或者從源數據加載來獲得更多item。

 protected void onCreate(Bundle savedInstanceState) {  // Configure the RecyclerView獲得RecylerView的實例  RecyclerView rvItems = (RecyclerView) findViewById(R.id.rvContacts);  LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);  recyclerView.setLayoutManager(linearLayoutManager);  // Add the scroll listener  rvItems.addOnScrollListener(new EndlessRecyclerViewScrollListener(linearLayoutManager) {   @Override   public void onLoadMore(int page, int totalItemsCount) {    // Triggered only when new data needs to be appended to the list    // Add whatever code is needed to append new items to the bottom of the list    customLoadMoreDataFromApi(page);    }  }); } // Append more data into the adapter // This method probably sends out a network request and appends new data items to your adapter.  public void customLoadMoreDataFromApi(int page) {  // Send an API request to retrieve appropriate data using the offset value as a parameter.  // --> Deserialize API response and then construct new objects to append to the adapter  // --> Notify the adapter of the changes }}

EndlessRecyclerView

public abstract class EndlessRecyclerViewScrollListener extends RecyclerView.OnScrollListener { // The minimum amount of items to have below your current scroll position // before loading more. private int visibleThreshold = 5; // The current offset index of data you have loaded private int currentPage = 0; // The total number of items in the dataset after the last load private int previousTotalItemCount = 0; // True if we are still waiting for the last set of data to load. private boolean loading = true; // Sets the starting page index private int startingPageIndex = 0; RecyclerView.LayoutManager mLayoutManager; public EndlessRecyclerViewScrollListener(LinearLayoutManager layoutManager) {  this.mLayoutManager = layoutManager; } public EndlessRecyclerViewScrollListener(GridLayoutManager layoutManager) {  this.mLayoutManager = layoutManager;  visibleThreshold = visibleThreshold * layoutManager.getSpanCount(); } public EndlessRecyclerViewScrollListener(StaggeredGridLayoutManager layoutManager) {  this.mLayoutManager = layoutManager;  visibleThreshold = visibleThreshold * layoutManager.getSpanCount(); } public int getLastVisibleItem(int[] lastVisibleItemPositions) {  int maxSize = 0;  for (int i = 0; i < lastVisibleItemPositions.length; i++) {   if (i == 0) {    maxSize = lastVisibleItemPositions[i];   }   else if (lastVisibleItemPositions[i] > maxSize) {    maxSize = lastVisibleItemPositions[i];   }  }  return maxSize; } // This happens many times a second during a scroll, so be wary of the code you place here. // We are given a few useful parameters to help us work out if we need to load some more data, // but first we check if we are waiting for the previous load to finish. @Override public void onScrolled(RecyclerView view, int dx, int dy) {  int lastVisibleItemPosition = 0;  int totalItemCount = mLayoutManager.getItemCount();  if (mLayoutManager instanceof StaggeredGridLayoutManager) {   int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null);   // get maximum element within the list   lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions);  } else if (mLayoutManager instanceof LinearLayoutManager) {   lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();  } else if (mLayoutManager instanceof GridLayoutManager) {   lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();  }  // If the total item count is zero and the previous isn't, assume the  // list is invalidated and should be reset back to initial state  if (totalItemCount < previousTotalItemCount) {   this.currentPage = this.startingPageIndex;   this.previousTotalItemCount = totalItemCount;   if (totalItemCount == 0) {    this.loading = true;   }  }  // If it's still loading, we check to see if the dataset count has  // changed, if so we conclude it has finished loading and update the current page  // number and total item count.  if (loading && (totalItemCount > previousTotalItemCount)) {   loading = false;   previousTotalItemCount = totalItemCount;  }  // If it isn't currently loading, we check to see if we have breached  // the visibleThreshold and need to reload more data.  // If we do need to reload some more data, we execute onLoadMore to fetch the data.  // threshold should reflect how many total columns there are too  if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) {   currentPage++;   onLoadMore(currentPage, totalItemCount);   loading = true;  } } // Defines the process for actually loading more data based on page public abstract void onLoadMore(int page, int totalItemsCount);}

注意問題:
 1.對于ListView,確定將綁定監聽器的步驟放在onCreate()的方法中
 2.為可加可靠的進行分頁,需要確定在向列表中添加新數據的時候先清理適配器中的數據
對于RecyclerView來說在通知適配器時推薦更細致的更新。
 3.對于RecyclerView來說確保在清除列表中的數據的時候迅速的通知適配器內容更新了,以便于可以觸發新的onScroll事件,重置自己 

展示進度條

為了在底部展示進度條證明ListView正在加載。我們可以在Adapter中進行設置,我們可以定義兩類,可以是進度條類型或者是文本表明達到了最底行,參考:http://guides.codepath.com/android/Endless-Scrolling-with-AdapterViews-and-RecyclerView

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 灵武市| 新余市| 贵定县| 犍为县| 庆城县| 凌源市| 叙永县| 楚雄市| 庄浪县| 璧山县| 邢台市| 浙江省| 苍山县| 乐昌市| 海丰县| 皋兰县| 印江| 久治县| 略阳县| 修武县| 定远县| 大厂| 娱乐| 富阳市| 琼海市| 石林| 佛坪县| 炉霍县| 龙井市| 德阳市| 上杭县| 遂昌县| 朔州市| 塔城市| 古丈县| 牙克石市| 萨嘎县| 泰兴市| 内乡县| 漳州市| 阜南县|