【问题标题】:onScrolled is being called without any user scrolling in recyclerViewonScrolled 被调用,没有任何用户在 recyclerView 中滚动
【发布时间】:2020-08-03 12:27:08
【问题描述】:

我正在尝试创建分页。为此,我在 viewModel 中使用带有页面查询的 MovieDb API 的改造调用:

fun getMovies(page: Int = 1) {
        launch {
            if (page == 1) {
                liveData.value =
                    State.ShowLoading
            }
            val list = withContext(Dispatchers.IO) {
                try {
                    val api: MovieApi? = RetrofitService.getClient()?.create(MovieApi::class.java)
                    val response =
                        api?.getPopularMoviesListCoroutine(BuildConfig.THE_MOVIE_DB_API_TOKEN, page)
                    if (response?.isSuccessful!!) {
                        val result = response.body()
                        val list = response?.body()?.results ?: emptyList()
                        val totalPage = response?.body()?.totalPages ?: 0
                        if (!result?.results.isNullOrEmpty()) {
                            movieDao.insertAll(result?.results!!)
                        }


                        Pair(totalPage, list)
                    } else {
                        Pair(
                            1, movieDao.getAll() ?: emptyList<Movie>()
                        )

                    }
                } catch (e: Exception) {
                    Log.e("Moviedatabase", e.toString())
                    Pair(
                        1, movieDao.getAll() ?: emptyList<Movie>()
                    )
                }
            }

            liveData.postValue(
                State.Result(
                    totalPage = list.first,
                    list = list.second
                )
            )
            liveData.value = State.HideLoading
        }
    }

在我的 Fragment 中,我使用了那个 viewModel:

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val viewModelProviderFactory = ViewModelProviderFactory(requireContext())
        movieListViewModel =
            ViewModelProvider(this, viewModelProviderFactory).get(MoviesListViewModel::class.java)
        return inflater.inflate(R.layout.fragment_movie_list, container, false)
    }

然后在绑定中,我在 recyclerView 滚动中调用 getMovies:

recyclerView.addOnScrollListener(object :PaginationListener(layoutManager){
            override fun loadMoreItems() {
                Log.d("load_more", "true --"+currentPage )
                isLoading = true
                currentPage++
                // mocking network delay for API call
                Handler().postDelayed({
                    movieListViewModel.getMovies(page = currentPage)
                }, 3000)            }

分页监听器:


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

        val visibleItemCount = layoutManager.childCount
        val totalItemCount = layoutManager.itemCount
        val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()

        if (!isLoading() && !isLastPage()) {
            if (visibleItemCount + firstVisibleItemPosition >= totalItemCount &&
                firstVisibleItemPosition >= 0 &&
                totalItemCount >= PAGE_SIZE) {
                loadMoreItems()
            }
        }
    }

另外在设置数据时我使用那个密封的类对象:

is MoviesListViewModel.State.Result -> {
                        itemCount = result.list.size
                        if (currentPage != PaginationListener.PAGE_START) {
                            movieListAdapter?.removeLoading()
                            Log.d("load_more", "remove loading")

                        }
                        movieListAdapter?.addItems(result.list)
                        if (currentPage < result.totalPage) {
                            movieListAdapter?.addLoading()
                            Log.d("load_more", "add loading")

                        } else {
                            isLastPage = true
                        }
                        isLoading = false

因此,总是调用 loadMoreItems。请给我解决方案

【问题讨论】:

    标签: android kotlin android-recyclerview retrofit2 android-viewmodel


    【解决方案1】:

    你是对的。每次创建活动时都会调用 onScroll 。 这是我处理分页的片段的一部分。 希望对你有帮助:

    //define out of method blocks (globaly):
    boolean loaded = false;  
    int page = 2;
    .
    .
    .
    
    //in onCreate method:
    list.setOnScrollListener(new AbsListView.OnScrollListener() {
    
        public void onScrollStateChanged(AbsListView view, int scrollState) {
        }
    
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    
            if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount != 0) {
    
                if (!loaded) {
                    loadMore(nextPage++);
                    loaded = true;
                }
    
            }
        }
    });
    
    .
    .
    .
    .
    .
    //after list filled (onResponse):
    int index = list.getFirstVisiblePosition();
    View v = list.getChildAt(0);
    int top = (v == null) ? 0 : v.getTop();
    list.setSelectionFromTop(index, top);
    loaded = false;
    

    如果你不明白,请告诉我更多解释并提供完整的课程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多