0

不同陣列尺寸的scrollListener使無盡的滾動 - 你可以找到我的問題和維倫的答案在這裏:無盡滾動RecyclerView與我目前使用的API

Adding items to Endless Scroll RecyclerView with ProgressBar at bottom

這可以創造奇蹟,當你有same每當您滾動時激活適配器的數據集大小例如,在Vilen的代碼中,他每次滾動時都會將數據集的大小增加相同數量,15。

但是,在現實世界中,情況往往不是這樣。您一直有不同的數據集大小。在我的示例中,我想要執行以下操作:

我想實施地理空間搜索,以便返回最接近我的地點列表。現在,如果我坐在沙漠中,我的REST API調用將返回距離我10公里內的地方,這可能只有4個地方(駱駝小屋,金字塔,水洞和椰子樹)。

在recyclerview中填充4個項目不會使recyclerview足夠長以允許它進一步滾動,以便我的應用程序將再次觸發API調用以找到更靠近我的位置。接下來的10公里(距離我目前的地點20公里)可能是一個有很多地方可以返回的城鎮,但由於recyclerview的時間不夠長,所以不會進行API調用。

我也做了一個微小的回購協議,以證明當recyclerview太短滾動監聽器不會被觸發:

https://github.com/Winghin2517/DissimilarDataSetSizeRV.git

我怎樣才能解決這個問題得到什麼?

我幾乎覺得應該觸發scrolllistener,直到recyclerview填滿屏幕,但是如何確定何時屏幕將被填滿,因爲回收站視圖 - 填充屏幕沒有回調,就我而言知道。

我曾試圖阻止改變boolean loading看,這將有助於但沒有布爾檢查負載的狀態,進度條不一定會被刪除導致這種類型的效果:

enter image description here

回答

0

感謝這個主題,我能夠確定recyclerview是否足夠長以滾動:How to know if a RecyclerView has enough content to scroll?

然後我用代碼玩了一下,它似乎以這種方式工作。

我創建了兩個新的變量:

final static String PROGRESS_BAR = "progressBar"; //this will be the unique object that will be added to the arraylist when you want to display the progress bar 
boolean progressBarAdded; //the progressbar must only be added once so this will keep track of it when it is added. 

    //adapter code is changed to take into account when the recyclerview can/cannot scroll 
    mAdapter.setOnLoadMoreListener(new MyAdapter.OnLoadMoreListener() { 
     @Override 
     public void onLoadMore() { 
      //add progress item 
      //we can scroll and progress bar is not yet added 
      if (!progressBarAdded && llm.findLastCompletelyVisibleItemPosition() != mAdapter.getItemCount() - 1) { 
       progressBarAdded = true; 
       myDataset.add(PROGRESS_BAR); 
       mAdapter.notifyItemInserted(myDataset.size() - 1); 
      } 

      Handler handler = new Handler(); 
      handler.postDelayed(new Runnable() { 
       @Override 
       public void run() { 
        //remove progress item 
        boolean removed = myDataset.remove(PROGRESS_BAR); 
        if (removed) { 
         mAdapter.notifyItemRemoved(myDataset.size()); 
         progressBarAdded = false; //progress bar is now removed 
        } 
        //add items one by one 
        for (int i = 0; i < 3; i++) { 
         myDataset.add("Item" + (myDataset.size() + 1)); 
         mAdapter.notifyItemInserted(myDataset.size()); 
        } 
       //we can scroll 
       if(llm.findLastCompletelyVisibleItemPosition()!=mAdapter.getItemCount()-1) { 
        mAdapter.setLoaded(); 
       } 
      } 
     }, 500); 

我再更改scrolllistener這樣的:

if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) { 

     final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); 
     recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { 
      @Override 
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
       super.onScrolled(recyclerView, dx, dy); 

       totalItemCount = linearLayoutManager.getItemCount(); 
       lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition(); 
       if (totalItemCount <= (lastVisibleItem + visibleThreshold)) { 
        // End has been reached 
        // Do something 
        if (onLoadMoreListener != null) { 
         onLoadMoreListener.onLoadMore(); 
        } 
        if (linearLayoutManager.findLastCompletelyVisibleItemPosition() != MyAdapter.this.getItemCount() - 1) { //determines whether the recyclerview is full or not. If not full, this will cause it to continue to load 
         loading = true; 
        } 
       } 
      } 
     }); 
    } 

另外,還要確保你考慮到新getItemType因爲每次檢測字符串「時progressBar「,它必須加載進度條的視圖框:

@Override 
public int getItemViewType(int position) { 
    return mDataset.get(position) != MainActivity.PROGRESS_BAR ? VIEW_ITEM : VIEW_PROG; 
} 
+0

所以你解決了這個問題還是你還需要幫助? –

+0

解決了。我不敢相信我能夠快速解決這個問題。它比我想象的要花費更少的時間。我無法將我的答案標記爲正確,但我會按照SO規則在2小時內完成答案。 – Simon

+0

那麼如果你有更好的方式來做到這一點,你可以自由發佈你的解決方案。我覺得我的方式有點冒險,但它似乎工作。 – Simon

0

你可以嘗試t他的做法(下面的代碼是從我的應用程序之一,所以你將不得不填補國內空白,我只補充說,將解決你的問題的部分)>

public class MainActivity extends AppCompatActivity implements AbsListView.OnScrollListener 
// Or use yourListView.setOnScrollListener(this); 
{ 

    int preLast = -1; 

    @Override 
    public void onScroll(AbsListView lw, final int aFirstVisibleItemIndex, final int aVisibleItemCount, final int aTotalItemsCount) { 
     int id = mListView.getId(); // Or use case android.R.id.list:  

     if(lw.getId() == id) { 
        // Sample calculation to determine if the last item is fully visible. 
      final int lastItem = aFirstVisibleItemIndex + aVisibleItemCount; 
      if(lastItem > 0 && lastItem == aTotalItemsCount) // lastItem > 0 helps to avoid continuous call if the list is empty. 
      { 
       if(preLast != lastItem) { //to avoid multiple calls for last item 
        preLast = lastItem; 

       } 
       } 
     } 
     } 
} 

@Override //it will be called before any calls to Adapter.getView(.....) 
public void onScrollStateChanged(AbsListView view, int scrollState) { 

} 

而現在,每當你決定有沒有更多的數據要從服務器中獲取(要在列表中填充更多項目),並且您希望避免使用listview繼續調用/激活(在繼續加載動畫時),您可以簡單地將preLast值設置爲lastItem值。

+0

我正在尋找recyclerview,而不是listview。 – Simon