2016-11-10 508 views
0

我有一個用戶的飼料,其中用戶的帖子將顯示,如果當前用戶跟着他們,目前我有loadMoreListener工作正常加載下一批圖像時,他們到達RecyclerView的底部。但是,當我到達列表中的最後一項(Feed只顯示50個帖子)時,它會嘗試加載更多並導致OutOfMemoryException。我已經限制了適配器中列表的大小,但是現在當用戶擊中底部停止顯示進度並停止OnLoadMoreListener觸發時,我似乎無法解決問題。這是我到目前爲止已經試過:onLoadMoreListener不會停止加載 - RecyclerView - Android

適配器構造:

public RecyclerViewAdapterAllFeeds(Context context, 
             final ArrayList<AllFeedsDataModel> previousPostsList, final boolean profile, RecyclerView recyclerView, final ProgressBar progressBar) { 
     this.context = context; 
     this.previousPostsList = previousPostsList; 
     this.profile = profile; 
     if(recyclerView.getLayoutManager() instanceof LinearLayoutManager){ 
      final LinearLayoutManager linearLayoutManager = (LinearLayoutManager)recyclerView.getLayoutManager(); 
      recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { 
       @Override 
       public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
        super.onScrolled(recyclerView, dx, dy); 
        progressBar.setVisibility(View.VISIBLE); 
         if (getItemCount() > LOADED_POSTS - 2) { 
          totalItemCount = getItemCount(); 
//       total_posts = getItemCount(); 
          lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition(); 
          if (lastVisibleItem <= TOTAL_POSTS) { 
           if (!loading && totalItemCount <= (lastVisibleItem)) { 
            if (onLoadMoreListener != null) { 
             onLoadMoreListener.onLoadMore(); 
            } 
            loading = true; 
           } 
          } 
         } 
       } 
      }); 
     } 
    } 

onLoadMoreListener

adapter = new RecyclerViewAdapterAllFeeds(getActivity(), latestUpdatesList, false, recyclerView, progressBar); 
          recyclerView.setAdapter(adapter);// set adapter on recyclerview 
          adapter.setOnLoadMoreListener(new RecyclerViewAdapterAllFeeds.OnLoadMoreListener() { 
           @Override 
           public void onLoadMore() { 
            refreshCount++; 
            populateRecyclerView(true, refreshCount); 
            adapter.update(updatesList); 
            adapter.setLoaded(); 
            System.out.println("load"); 
           } 
          }); 
          adapter.notifyDataSetChanged();// Notify the adapter 
          progressBar.setIndeterminate(false); 
          progressBar.setVisibility(View.INVISIBLE); 

我的問題是我怎麼能阻止它加載如果總員額少比限制條件還是知道何時最終產品可見?

回答

1

首先創建EndlessRecyclerViewScrollListener.java:

import android.support.v7.widget.GridLayoutManager; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.support.v7.widget.StaggeredGridLayoutManager; 

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); 

} 

然後以這種方式實現:

recyclerView.addOnScrollListener(new EndlessRecyclerViewScrollListener(recyclerView.getLayoutManager()) { 
      @Override 
      public void onLoadMore(int page, int totalItemsCount) { 

       //TODO Add logic for load more posts or show message if posts is ended. 

      } 
     }); 
+0

你能解釋一下,如果我想在將來改變它,這將如何對我的情況有利,它是否適合任何數量的帖子? – BIW

+0

當您到達列表的底部時,請刪除OnScrollListener。是的,這是與所有號碼後。 – Ruben

+0

虐待它,讓你知道芽。 – BIW

0

退房,我用了無盡的滾動代碼:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { 
      @Override 
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
       super.onScrolled(recyclerView, dx, dy); 
//    if (BuildConfig.DEBUG) 
//     Log.d(TAG, "onScrolled: [x, y]=[" + dx + ", " + dy + "], count=[" + recyclerView.getLayoutManager().getChildCount() + ", " + recyclerView.getLayoutManager().getItemCount() + ", " + ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition() + "]"); 
       if (hasMoreRequest) { 
        if (dy > 0) { //check for scroll down 
         checkForMoreLoad(); 
        } 
       } 
      } 
     }); 

private void checkForMoreLoad() { 
     final Handler handler = new Handler(); 
     Runnable checkForMoreData = new Runnable() { 
      @Override 
      public void run() { 
       if (null != recyclerView) { 
        int visibleItemCount = recyclerView.getLayoutManager().getChildCount(); 
        int totalItemCount = recyclerView.getLayoutManager().getItemCount(); 
        int pastVisibleItems = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition(); 
        onScrollToLoad(visibleItemCount, pastVisibleItems, totalItemCount); 
       } 
      } 
     }; 
     handler.postDelayed(checkForMoreData, 100); 
    } 

    private void onScrollToLoad(int visibleItemCount, int pastVisibleItems, int totalItemCount) { 
     if ((visibleItemCount + pastVisibleItems) + 4 >= totalItemCount && hasMoreRequest) { 
      if (BuildConfig.DEBUG) 
       Log.d(TAG, "onScroll lastInScreen - so load more"); 
      startNetworkCall(page + 1); 
     } 
    } 

而且從API獲得數據後,如果有更多數據,我將再次致電checkForMoreLoad()

onScrollToLoad()的行有4位於其中。這是爲了在滾動結束之前手動啓動API。

+0

不好意思給它發芽,讓你知道 – BIW

+0

@BIW當然。試着告訴我它是怎麼回事 –

+0

我用了另一個答案哥們,還沒有測試過 – BIW