RecyclerView Jumps in middle of the list when paginatining
Asked Answered
C

2

8

I have this page which I've setUp with MVVM and pagination using RecyclerView and Pull to refresh. Clicking on some items in this RecyclerView will navigate to another fragment.

My problem is whenever I load the page for the first time and scroll all the way down in works perfectly. Pull to refresh will work as well.

But when I navigate to the other fragment and get back, scroll all the way top, swipe to refresh: The RecyclerView will jump to the middle of the page (Right on the item where I clicked to navigate to the other fragment)

My Fragment

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val adapter = GroupAdapter<ViewHolder>().apply { add(mainSection) }
        val gridLayoutManager = GridLayoutManager(activity, adapter.spanCount)
        gridLayoutManager.spanSizeLookup = adapter.spanSizeLookup
        with(recyclerView) {
            layoutManager = gridLayoutManager
            setHasFixedSize(true)
            addOnScrollListener(PaginationScrollListener {
                viewModel.onEndOfList()
            })
        }
        recyclerView.adapter = adapter


        pullToRefresh.apply {
            setProgressBackgroundColorSchemeColor(
                ContextCompat.getColor(context, R.color.window_level_2)
            )
            setColorSchemeColors(ContextCompat.getColor(context, R.color.brand_primary))
            setOnRefreshListener { viewModel.onRefresh() }
        }
    }

My ViewModel

    fun onRefresh() {
        page = 0
        widgetItems.clear()
        _widgetListObservable.postValue(widgetItems)
        finishedLoading = false
        isFirstFetch = true
        getItems()
    }

private fun getItems() {
        isLoading = true
        dataSource.getPage(page)
            .subscribeOn(backgroundThread.getScheduler())
            .observeOn(mainThread.getScheduler())
            .flatMap {
                Flowable.fromIterable(it)
                    .toList()
                    .toFlowable()
            }
            .doAfterTerminate {
                isLoading = false
            }
            .subscribe(Consumer {
                finishedLoading = it.isEmpty()

                if (isFirstFetch && finishedLoading) {
                    _isMyPaymentsEmptyObservable.postValue(true)
                }
                widgetItems.addAll(it)
                _widgetListObservable.postValue(widgetItems)
                page++
                isFirstFetch = false
            }, {
              println(it)
            })

EDIT when I remove the onRefreshListener on the swipeToRefreshin the first fragment it works. I have no idea why this happens?

Thanks for reading.

Courlan answered 26/12, 2019 at 10:17 Comment(2)
Check if setHasFixedSize(false) works. Also in refresh part you can use: scrollToPositionWithOffset (int position, int offset) For recyclerview to get back at that p position.Decent
Actually the problem was in onDestroyView, I didn't remove the pullToRefresh clickListener in the first fragment. when I did it worked correctly. I have pull to refresh in both pages tho. any idea why?Courlan
P
7

Try adding this two attribute to your parent layout of the activity.

android:focusableInTouchMode="true"
android:focusable="true"

RecyclerView might be storing the focusable to last item you have clicked or there are times when RecylerView autoscroll on data loading.

Powers answered 4/1, 2020 at 6:6 Comment(4)
Yes, this did work out. pullToRefresh.setOnClickListener(null) worked as wellCourlan
I did. Thanks ^_^Courlan
Tried no luck ,I think issue with pagination.Cantonese
for me new PagedList.Config.Builder().setPageSize(100).build(); worksCantonese
C
0

After trying DataSource invalidate() method no luck. so I changed page size to 100 and now its loading to 0 position

PagedList.Config config=new PagedList.Config.Builder().setPageSize(100).build();
    dataSourceFactory = inventoryTransactionDao.getAllInventoryTransactions(new SimpleSQLiteQuery(queryString, args.toArray()));
    LiveData<PagedList<TransactionHistory>> livePageList= new LivePagedListBuilder<>(dataSourceFactory,config).build();
Cantonese answered 8/9, 2021 at 12:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.