【问题标题】:On scrolled is only called at first load and never againOn scrolled 仅在第一次加载时调用,不再调用
【发布时间】:2019-11-28 23:30:44
【问题描述】:

我正在尝试实现无限滚动,但我无法让它工作,正如我从我放置的日志中看到的那样,onScrolled 方法仅在页面首次加载时调用一次,而不是之后,即使我一直滚动到底部。我尝试了多次上下,但它再也没有被调用过。

它是否与它位于 swipeRefreshLayout 中有关?

这是我的代码

初始化变量

lateinit var lastVisible: DocumentSnapshot
var isScrolling = false
var isLastItemReached = false

从服务器函数中获取数据

fun listenToQuestions() {

    questionsRowLayoutAdapter.clear()
    questionsBlockLayoutAdapter.clear()



    db.collection("questions").whereEqualTo("language", currentLanguage)
        .orderBy("last_interaction", Query.Direction.DESCENDING).limit(10)
        .get().addOnSuccessListener {

            for (document in it) {
                val questionObject = document.toObject(Question::class.java)

                           questionsAdapter.add(
                                (SingleBoardBlock(
                                    questionObject,
                                    activity as MainActivity
                                ))
                            )

            }
            Toast.makeText(this.context, "first batch", Toast.LENGTH_SHORT).show()

            questionsAdapter.notifyDataSetChanged()

            lastVisible = it.documents[it.size() - 1]

            val onScrollListener = object : RecyclerView.OnScrollListener() {
                override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                    super.onScrollStateChanged(recyclerView, newState)
                    if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                        isScrolling = true
                        Toast.makeText(activity, "scrolling", Toast.LENGTH_SHORT).show()
                        Log.d("itemsvaues", "new state statement true")
                    } else {
                        Log.d("itemsvaues", "new state statement false")
                    }
                }

                override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                    super.onScrolled(recyclerView, dx, dy)

                    val thisLayoutManager = recyclerView.layoutManager as LinearLayoutManager

                    val firstVisibleItem = thisLayoutManager.findFirstVisibleItemPosition()
                    val visibleItemCount = thisLayoutManager.childCount
                    val totalItemCount = thisLayoutManager.itemCount

                    val countCheck = firstVisibleItem + visibleItemCount == totalItemCount
                    Log.d("itemsvaues", "$firstVisibleItem $visibleItemCount $totalItemCount $countCheck")
                    Log.d("itemsvaues", "is scrolling $isScrolling")
                    Log.d("itemsvaues", "last item reached $isLastItemReached")


                    if (isScrolling && countCheck && !isLastItemReached) {
                        isScrolling = false
                        Log.d("itemsvaues", "if happened")

                        db.collection("questions").whereEqualTo("language", currentLanguage)
                            .orderBy("last_interaction", Query.Direction.DESCENDING).startAfter(lastVisible)
                            .limit(10).get()
                            .addOnSuccessListener { querySnapshot ->

                                for (document in querySnapshot) {
                                    val questionObject = document.toObject(Question::class.java)

                           questionsAdapter.add(
                                (SingleBoardBlock(
                                    questionObject,
                                    activity as MainActivity
                                ))
                            )

                                    }
                                }
                                Toast.makeText(activity, "next batch", Toast.LENGTH_SHORT).show()

                                questionsAdapter.notifyDataSetChanged()

                                lastVisible = querySnapshot.documents[querySnapshot.size() - 1]
                                Log.d("itemsvaues", "next query happened")

                                if (querySnapshot.size() < 10) {
                                    isLastItemReached = true
                                    Toast.makeText(activity, "reached last", Toast.LENGTH_SHORT).show()
                                    Log.d("itemsvaues", "last item reached")

                                }
                            }
                    } else {
                        Log.d("itemsvaues", "if didn't happen")
                    }
                }
            }
            questionsRecycler.addOnScrollListener(onScrollListener)
        }
}

这些是日志:

2019-07-20 12:48:49.149 29888-29888/io.poolclub D/itemsvaues: 0 10 10 true
2019-07-20 12:48:49.149 29888-29888/io.poolclub D/itemsvaues: is scrolling false
2019-07-20 12:48:49.149 29888-29888/io.poolclub D/itemsvaues: last item reached false
2019-07-20 12:48:49.149 29888-29888/io.poolclub D/itemsvaues: if didn't happen
2019-07-20 12:48:52.181 29888-29888/io.poolclub D/itemsvaues: new state statement true
2019-07-20 12:48:52.328 29888-29888/io.poolclub D/itemsvaues: new state statement false
2019-07-20 12:48:52.530 29888-29888/io.poolclub D/itemsvaues: new state statement false
2019-07-20 12:48:53.481 29888-29888/io.poolclub D/itemsvaues: new state statement true
2019-07-20 12:48:53.645 29888-29888/io.poolclub D/itemsvaues: new state statement false

【问题讨论】:

    标签: android kotlin android-recyclerview infinite-scroll onscrolllistener


    【解决方案1】:

    可能不再对原始海报有用,但对遇到相同问题的其他人:

    就我而言,问题在于我忘记了我已将RecyclerView 放入NestedScrollView 并将其设置为android:nestedScrollingEnabled="false",这确实使监听器只触发一次。您可以将侦听器添加到 NestedScrollView 然后,或者查看以下问题中讨论的某些选项是否可以帮助您: Recyclerview onscrolllistener not working when setNestedScrollingEnabled to false

    当然还有其他原因,但这是最容易遇到的原因之一。

    【讨论】:

      【解决方案2】:

      你可以试试这个代码

      listview.addOnScrollListener(new RecyclerView.OnScrollListener() {
      
                  public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                      super.onScrolled(recyclerView, dx, dy);
      
      
                      visibleItemCount = manager.getChildCount();
                      totalItemCount = manager.getItemCount();
                      pastVisiblesItems = manager.findFirstVisibleItemPosition();
      
                      if (dy > 0 && pastVisiblesItems >= totalItemCount && !isLoading) {
                          isLoading = true;
                          LoadMoreData();
                      }
      
                  }
      
              });
      

      使用此代码,您可以滚动到列表末尾并加载新信息 如果您需要从第 10 项到要加载的列表末尾的信息

      改变

      if (dy > 0 && pastVisiblesItems >= totalItemCount && !isLoading) {
         isLoading = true;
         LoadMoreData();
      }
      

      if (dy > 0 && pastVisiblesItems >= totalItemCount - 10 && !isLoading) {
         isLoading = true;
         LoadMoreData();
      }
      

      【讨论】:

      • 我的问题不是我从教程中复制的代码,它似乎是一个很好的代码,我的问题是 onScrolled 没有在应该调用的时候调用。所以更改为这段代码不会有太大变化,因为onScrolled 仍然不会被调用
      • 这个答案确实根本没有回答问题。
      猜你喜欢
      • 2017-09-26
      • 2021-01-25
      • 2020-09-04
      • 1970-01-01
      • 2017-08-25
      • 1970-01-01
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多