【问题标题】:How to detect when user have scrolled to the top most item in a RecyclerView如何检测用户何时滚动到 RecyclerView 中最顶部的项目
【发布时间】:2017-01-25 09:14:06
【问题描述】:

我已尝试编写以下代码

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
  super.onScrolled(recyclerView, dx, dy);
  if(dy > 0){
    //scrolling up
  } else {
    //scrolling down
    int pastVisibleItems = linearLayoutManager.findFirstVisibleItemPosition();
    if (pastVisibleItems  == 0) {
      Toast.makeText(getContext(),"Top most item",Toast.LENGTH_SHORT).show();
    }
  }
}

但它不起作用。我还尝试使用 android 的 SwipeRefreshLayout 来执行此操作,因为它可以执行我想要的操作,能够检测用户何时滚动到最顶部的项目。我决定不使用它,因为我似乎无法阻止加载指示器弹出(我根本不想看到加载指示器出现)。

所以,基本上我想做的是:

  1. 检查用户滚动
  2. 它已经是最上面的项目了吗?
  3. 如果是,则执行某些操作,如果不是,则不执行任何操作

知道如何做到这一点吗?

谢谢。

【问题讨论】:

    标签: android scroll android-recyclerview


    【解决方案1】:

    我自己解决了我的问题。我改用下面的代码

    private boolean isUserScrolling = false;
    private boolean isListGoingUp = true;
    

    然后在RecyclerView中的OnScrollListener

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        //detect is the topmost item visible and is user scrolling? if true then only execute
        if(newState ==  RecyclerView.SCROLL_STATE_DRAGGING){
            isUserScrolling = true;
            if(isListGoingUp){
                //my recycler view is actually inverted so I have to write this condition instead
                if(linearLayoutManager.findLastCompletelyVisibleItemPosition() + 1 == list.size()){
                    Handler handler = new Handler();
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            if(isListGoingUp) {
                                if (linearLayoutManager.findLastCompletelyVisibleItemPosition() + 1 == list.size()) {
                                    Toast.makeText(getContext(),"exeute something", Toast.LENGTH_SHORT).show();
                                }
                            }
                        }
                    },50);
                    //waiting for 50ms because when scrolling down from top, the variable isListGoingUp is still true until the onScrolled method is executed
                }
            }
        }
    }
    
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        if(isUserScrolling){
            if(dy > 0){
                //means user finger is moving up but the list is going down
                isListGoingUp = false;
            }
            else{
                //means user finger is moving down but the list is going up
                isListGoingUp = true;
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      用下面的代码替换你的代码:

      @Override
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
      
        int pastVisibleItems = linearLayoutManager.findFirstCompletelyVisibleItemPosition();
        if (pastVisibleItems  == 0) {
          Toast.makeText(getContext(),"Top most item",Toast.LENGTH_SHORT).show();                
        }
      }
      

      它对我有用,如果您遇到任何错误,请发表评论。

      【讨论】:

      • 实际上我的列表是倒置的,我使用此代码代替 if (pastVisibleItems+1 == historyList.size()) Toast.makeText(getContext(),"Top most item",Toast.LENGTH_SHORT)。显示();但我的 pastVisibleItems 是 244,而列表实际上是 250
      • @carlos 你的过去VisibleItems 是什么?哪个值存储在该变量中
      • 嗯,需要注意的是 1) 我的 list.size() 将返回 250。2) 我的 RecyclerView 已设置为 Reverse,这意味着最上面的项目的位置应该是 249。3)由于屏幕大小,RecyclerView 一次只能显示 7 个项目。 4)当我滚动到最顶端时,过去的VisibleItems 只返回244。所以它不起作用......
      • 如果你的项目比你的屏幕大,这种方法不起作用。这样 'findFirstCompletelyVisibleItemPosition()' 总是返回 -1
      • 是的,而不是尝试 findFirstVisibleItemPosition() 这个函数可能会起作用@Katharina
      【解决方案3】:

      您可以使用代码轻松做到这一点

      recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
          @Override
          public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
              super.onScrollStateChanged(recyclerView, newState);
      
              if(newState ==  RecyclerView.SCROLL_STATE_DRAGGING) {
                  isUserScrolling = true;
              }
          }
      
          @Override
          public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
      
              super.onScrolled(recyclerView, dx, dy);
      
              if(isUserScrolling){
                  if(dy > 0){
                     //Scroll list Down
                  }
                  else{
                      if(!recyclerView.canScrollVertically(-1)){
      
                        //This Your Top View do Something
                      }
                  }
              }
          }
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-01-15
        • 2020-01-01
        • 1970-01-01
        • 2016-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多