2016-03-21 17 views
14

Tôi có mã này cho RecyclerView.Phát hiện khi RecyclerView đạt đến vị trí thấp nhất trong khi di chuyển

recyclerView = (RecyclerView)rootview.findViewById(R.id.fabric_recyclerView); 
    recyclerView.setLayoutManager(layoutManager); 
    recyclerView.addItemDecoration(new RV_Item_Spacing(5)); 
    FabricAdapter fabricAdapter=new FabricAdapter(ViewAdsCollection.getFabricAdsDetailsAsArray()); 
    recyclerView.setAdapter(fabricAdapter); 

Tôi cần biết khi nào RecyclerView đạt đến vị trí thấp nhất trong khi cuộn. Có thể không? Nếu có, làm thế nào?

+0

Thử http://stackoverflow.com/questions/27841740/how-to-know-whether-a-recyclerview-linearlayoutmanager-is-scrolled-to-top-or- b – Raghavendra

+0

http: // sta ckoverflow.com/questions/26543131/how-to-implement-endless-list-with-recyclerview –

+1

recyclerView.canScrollVertically (int direction); Thông số như thế nào chúng ta phải vượt qua đây? – Adrian

Trả lời

25

Chỉ cần triển khai addOnScrollListener() trên recyclerview của bạn. Sau đó, bên trong trình lắng nghe cuộn thực hiện mã bên dưới.

RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() { 
     @Override 
     public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
      if (mIsLoading) 
       return; 
      int visibleItemCount = mLayoutManager.getChildCount(); 
      int totalItemCount = mLayoutManager.getItemCount(); 
      int pastVisibleItems = mLayoutManager.findFirstVisibleItemPosition(); 
      if (pastVisibleItems + visibleItemCount >= totalItemCount) { 
       //End of list 
      } 
     } 
    }; 
+1

Bạn có thể giải thích một chút về mIsLoading không? bạn đang thiết lập nó ở đâu hoặc thay đổi giá trị. – MiguelHincapieC

+0

nạp tải chỉ là một biến boolean cho biết chế độ xem có tương tác hay không. Ví dụ; nếu ứng dụng đang điền vào recyclerview, thì việc tải nạp sẽ đúng và trở thành sai khi danh sách đã được điền. –

+0

ohh ok, tăng bạn cho câu trả lời. Tôi mặc dù nó có vai trò quan trọng hơn xD. – MiguelHincapieC

3

Có triển khai của tôi, nó rất hữu ích cho StaggeredGridLayout.

Cách sử dụng:

private EndlessScrollListener scrollListener = 
     new EndlessScrollListener(new EndlessScrollListener.RefreshList() { 
      @Override public void onRefresh(int pageNumber) { 
       //end of the list 
      } 
     }); 

rvMain.addOnScrollListener(scrollListener); 

Listener thực hiện:

class EndlessScrollListener extends RecyclerView.OnScrollListener { 
private boolean isLoading; 
private boolean hasMorePages; 
private int pageNumber = 0; 
private RefreshList refreshList; 
private boolean isRefreshing; 
private int pastVisibleItems; 

EndlessScrollListener(RefreshList refreshList) { 
    this.isLoading = false; 
    this.hasMorePages = true; 
    this.refreshList = refreshList; 
} 

@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
    super.onScrolled(recyclerView, dx, dy); 
    StaggeredGridLayoutManager manager = 
      (StaggeredGridLayoutManager) recyclerView.getLayoutManager(); 

    int visibleItemCount = manager.getChildCount(); 
    int totalItemCount = manager.getItemCount(); 
    int[] firstVisibleItems = manager.findFirstVisibleItemPositions(null); 
    if (firstVisibleItems != null && firstVisibleItems.length > 0) { 
     pastVisibleItems = firstVisibleItems[0]; 
    } 

    if (visibleItemCount + pastVisibleItems >= totalItemCount && !isLoading) { 
     isLoading = true; 
     if (hasMorePages && !isRefreshing) { 
      isRefreshing = true; 
      new Handler().postDelayed(new Runnable() { 
       @Override public void run() { 
        refreshList.onRefresh(pageNumber); 
       } 
      }, 200); 
     } 
    } else { 
     isLoading = false; 
    } 
} 

public void noMorePages() { 
    this.hasMorePages = false; 
} 

void notifyMorePages() { 
    isRefreshing = false; 
    pageNumber = pageNumber + 1; 
} 

interface RefreshList { 
    void onRefresh(int pageNumber); 
} } 
+0

Tại sao phải thêm 200 mili giây để gọi lại? – Mani

+0

@Mani Tôi không nhớ chính xác vào lúc này, nhưng có lẽ tôi đã thực hiện nó chỉ để có hiệu ứng mượt mà ... –

23

đó cũng là một cách đơn giản để làm điều đó

rv_convo.addOnScrollListener(new RecyclerView.OnScrollListener() { 
    @Override 
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 
     super.onScrollStateChanged(recyclerView, newState); 

     if (!recyclerView.canScrollVertically(1)) { 
      Toast.makeText(ChatDetailsActivity.this,"LAst",Toast.LENGTH_LONG).show(); 

     } 
    } 
}); 

số nguyên hướng: -1 lên , 1 cho xuống, 0 sẽ luôn trả về false.

+0

onScrolled() ngăn phát hiện xảy ra hai lần. –

+0

hãy xem https://stackoverflow.com/a/48514857/6674369 –

1

Tôi cũng đang tìm kiếm câu hỏi này, nhưng tôi không tìm ra câu trả lời mà tôi hài lòng, vì vậy tôi tạo ra nhận thức riêng của recyclerView:

class CustomRecyclerView: RecyclerView{ 

    abstract class TopAndBottomListener{ 
     open fun onBottomNow(onBottomNow:Boolean){} 
     open fun onTopNow(onTopNow:Boolean){} 
    } 


    constructor(c:Context):this(c, null) 
    constructor(c:Context, attr:AttributeSet?):super(c, attr, 0) 
    constructor(c:Context, attr:AttributeSet?, defStyle:Int):super(c, attr, defStyle) 


    private var linearLayoutManager:LinearLayoutManager? = null 
    private var topAndBottomListener:TopAndBottomListener? = null 
    private var onBottomNow = false 
    private var onTopNow = false 
    private var onBottomTopScrollListener:RecyclerView.OnScrollListener? = null 


    fun setTopAndBottomListener(l:TopAndBottomListener?){ 
     if (l != null){ 
      checkLayoutManager() 

      onBottomTopScrollListener = createBottomAndTopScrollListener() 
      addOnScrollListener(onBottomTopScrollListener) 
      topAndBottomListener = l 
     } else { 
      removeOnScrollListener(onBottomTopScrollListener) 
      topAndBottomListener = null 
     } 
    } 

    private fun createBottomAndTopScrollListener() = object :RecyclerView.OnScrollListener(){ 
     override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { 
      checkOnTop() 
      checkOnBottom() 
     } 
    } 

    private fun checkOnTop(){ 
     val firstVisible = linearLayoutManager!!.findFirstCompletelyVisibleItemPosition() 
     if(firstVisible == 0 || firstVisible == -1 && !canScrollToTop()){ 
      if (!onTopNow) { 
       onTopNow = true 
       topAndBottomListener?.onTopNow(true) 
      } 
     } else if (onTopNow){ 
      onTopNow = false 
      topAndBottomListener?.onTopNow(false) 
     } 
    } 

    private fun checkOnBottom(){ 
     var lastVisible = linearLayoutManager!!.findLastCompletelyVisibleItemPosition() 
     val size = linearLayoutManager!!.itemCount - 1 
     if(lastVisible == size || lastVisible == -1 && !canScrollToBottom()){ 
      if (!onBottomNow){ 
       onBottomNow = true 
       topAndBottomListener?.onBottomNow(true) 
      } 
     } else if(onBottomNow){ 
      onBottomNow = false 
      topAndBottomListener?.onBottomNow(false) 
     } 
    } 


    private fun checkLayoutManager(){ 
     if (layoutManager is LinearLayoutManager) 
      linearLayoutManager = layoutManager as LinearLayoutManager 
     else 
      throw Exception("for using this listener, please set LinearLayoutManager") 
    } 

    private fun canScrollToTop():Boolean = canScrollVertically(-1) 
    private fun canScrollToBottom():Boolean = canScrollVertically(1) 
} 

sau đó trong hoạt động của bạn/đoạn:

override fun onCreate() { 
    customRecyclerView.layoutManager = LinearLayoutManager(context) 
} 

override fun onResume() { 
    super.onResume() 
    customRecyclerView.setTopAndBottomListener(this) 
} 

override fun onStop() { 
    super.onStop() 
    customRecyclerView.setTopAndBottomListener(null) 
} 

hy vọng nó sẽ làm hỏng ai đó ;-)

Các vấn đề liên quan