欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android代碼實(shí)現(xiàn)AdapterViews和RecyclerView無(wú)限滾動(dòng)

 更新時(shí)間:2021年01月02日 09:14:15   作者:qq_34767498  
這篇文章主要為大家詳細(xì)介紹了Android代碼實(shí)現(xiàn)AdapterViews和RecyclerView無(wú)限滾動(dòng)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

應(yīng)用的一個(gè)共同的特點(diǎn)就是當(dāng)用戶歡動(dòng)時(shí)自動(dòng)加載更多的內(nèi)容,這是通過(guò)用戶滑動(dòng)觸發(fā)一定的閾值時(shí)發(fā)送數(shù)據(jù)請(qǐng)求實(shí)現(xiàn)的。

相同的是:信息實(shí)現(xiàn)滑動(dòng)的效果需要定義在列表中最后一個(gè)可見(jiàn)項(xiàng),和某些類(lèi)型的閾值以便于開(kāi)始在最后一項(xiàng)到達(dá)之前開(kāi)始抓取數(shù)據(jù),實(shí)現(xiàn)無(wú)限的滾動(dòng)。

實(shí)現(xiàn)無(wú)限滾動(dòng)的現(xiàn)象的重要之處就在于在用戶滑動(dòng)到最低端之前就行數(shù)據(jù)的獲取,所以需要加上一個(gè)閾值來(lái)幫助實(shí)現(xiàn)獲取數(shù)據(jù)的預(yù)期。

使用ListView和GridView實(shí)現(xiàn)

每個(gè)AdapterView 例如ListView 和GridView 當(dāng)用戶開(kāi)始進(jìn)行滾動(dòng)操作時(shí)候都會(huì)觸發(fā)OnScrollListener .使用這個(gè)系統(tǒng)我們就可以定義一個(gè)基本的EndlessScrollListener ,通過(guò)創(chuàng)造繼承OnScrollListener 的類(lèi)來(lái)支持大多數(shù)情況下的使用。

package com.codepath.customadapter;

import android.widget.AbsListView;

/**
 * Created by Administrator on 2016/7/11.
 */
public abstract class EndlessScrollListener implements AbsListView.OnScrollListener {
 //在你滑動(dòng)項(xiàng)下最少為多少時(shí)開(kāi)始加載數(shù)據(jù)
 private int visibleThreshold = 5;
 //已經(jīng)加載數(shù)據(jù)的當(dāng)前頁(yè)碼
 private int currentPage = 0;
 //上一次加載數(shù)據(jù)后數(shù)據(jù)庫(kù)的數(shù)據(jù)量
 private int previousTotalItemCount = 0;
 //我們是否在等待最后一組數(shù)據(jù)的加載
 private boolean loading = true;
 //設(shè)置開(kāi)始頁(yè)的下標(biāo)
 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;
 }
 //這個(gè)方法可能會(huì)在滑動(dòng)調(diào)用很多次,所以在設(shè)計(jì)時(shí)要保持謹(jǐn)慎
 //我們需要一些有用的參數(shù)來(lái)幫助我們,當(dāng)我們需要加載更多數(shù)據(jù)的時(shí)候
 //但是我們首先要檢查是否我們?cè)诘却惹暗募虞d結(jié)束

//onScroll()當(dāng)列表或網(wǎng)格視圖被滾動(dòng)后將會(huì)調(diào)用,參數(shù)一:報(bào)告狀態(tài)的視圖參數(shù)二:第一個(gè)可以看見(jiàn)的項(xiàng)的下標(biāo),參數(shù)三:可見(jiàn)項(xiàng)的數(shù)量參數(shù)四:listAdapter中所有的項(xiàng)數(shù)
 @Override
 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

 //如果總項(xiàng)數(shù)為0,而且先前沒(méi)有項(xiàng),那么這個(gè)列表是無(wú)效的應(yīng)該被設(shè)定為初始狀態(tài)
 if (totalItemCount < previousTotalItemCount) {
  this.currentPage = this.startingPageIndex;
  this.previousTotalItemCount = totalItemCount;
  if (totalItemCount == 0) {this.loading = true;}
 }
 //如果仍在加載中我們可以檢查一下數(shù)據(jù)集合是否改變了,如果改變的話那就是已經(jīng)完成了loading需要更新當(dāng)前
 //頁(yè)數(shù)和數(shù)據(jù)總量
 if (loading && (totalItemCount > previousTotalItemCount)) {
  loading = false;
  previousTotalItemCount = totalItemCount;
  currentPage++;
 }
 //如果當(dāng)前沒(méi)有加載,我們需要檢查當(dāng)前是否達(dá)到了閾值,如果是的話我們需要
 //加載更多的數(shù)據(jù),執(zhí)行onLoadMore
 if (!loading && (firstVisibleItem + visibleItemCount + visibleThreshold) >= totalItemCount) {
  loading = onLoadMore(currentPage + 1, totalItemCount);
 }
 }
 //定義實(shí)際加載數(shù)據(jù)的過(guò)程,如果數(shù)據(jù)加載完成返回false,如果正在加載返回true;
 public abstract boolean onLoadMore(int page, int totalItemCount);

 @Override
 public void onScrollStateChanged(AbsListView view, int scrollState) {
 //不采取動(dòng)作
 }
}

要注意的是這是一個(gè)抽象的類(lèi),為了要使用這些,必須繼承這個(gè)基本的類(lèi)并且實(shí)現(xiàn)onLoadMore()方法實(shí)際的獲取數(shù)據(jù), 我們?cè)谝粋€(gè)活動(dòng)中定義一個(gè)匿名的類(lèi)來(lái)繼承EndlessScrollListener然后將其連接AdapterView上

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

現(xiàn)在當(dāng)用戶滑動(dòng)并且觸發(fā)閾值時(shí)會(huì)自動(dòng)觸發(fā)onloadMore() 方法,而且監(jiān)聽(tīng)器給予了對(duì)于頁(yè)數(shù)和數(shù)據(jù)總量的訪問(wèn)權(quán)限。

實(shí)現(xiàn)RecyclerView的無(wú)限滑動(dòng)

我們可以使用相同的方法來(lái)定義一個(gè)接口EndlessRecyclerViewScrollListener 然后定義一個(gè)onLoadMore() 的方法來(lái)進(jìn)行實(shí)現(xiàn)。由于LayoutManager負(fù)責(zé)項(xiàng)的生成和滑動(dòng)的管理,我們需要一個(gè)LayoutManage的實(shí)例來(lái)收集必要的信息。
實(shí)現(xiàn)必要的分頁(yè)需要這樣的步驟:
1).直接復(fù)制EndlessRecyclerViewScrollListener.java
2).調(diào)用addOnScrollListener(...) 在RecyclerView 中來(lái)實(shí)現(xiàn)無(wú)限的分頁(yè),傳遞EndlessRecyclerViewScrollListener的實(shí)例來(lái)實(shí)現(xiàn)onLoadMore 方法來(lái)決定什么時(shí)候來(lái)加載新的數(shù)據(jù)
3).在onLoadMore 方法中通過(guò)發(fā)送網(wǎng)絡(luò)請(qǐng)求或者從源數(shù)據(jù)加載來(lái)獲得更多item。

 protected void onCreate(Bundle savedInstanceState) {
 // Configure the RecyclerView獲得RecylerView的實(shí)例
 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);

}

注意問(wèn)題:
 1.對(duì)于ListView,確定將綁定監(jiān)聽(tīng)器的步驟放在onCreate()的方法中
 2.為可加可靠的進(jìn)行分頁(yè),需要確定在向列表中添加新數(shù)據(jù)的時(shí)候先清理適配器中的數(shù)據(jù)
對(duì)于RecyclerView來(lái)說(shuō)在通知適配器時(shí)推薦更細(xì)致的更新。
 3.對(duì)于RecyclerView來(lái)說(shuō)確保在清除列表中的數(shù)據(jù)的時(shí)候迅速的通知適配器內(nèi)容更新了,以便于可以觸發(fā)新的onScroll事件,重置自己 

展示進(jìn)度條

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論