idanatz / OneAdapter

A Viewholderless Adapter for RecyclerView, who supports builtin diffing, states (paging, empty...), events (clicking, swiping...), and more.
MIT License
470 stars 45 forks source link

Adapter stops loading data if scrolled rapidly #5

Closed mehul4795 closed 5 years ago

mehul4795 commented 5 years ago

I am using OneAdapter along with the Paging module to load images gradually from an API. The problem is that if I scroll the list rapidly the paging stops and no more data is loaded after 3-4 pages.

I am attaching the all the necessary code that I am using below.

HomeFragment

class HomeFragment : BaseFragment() {
private val viewModel by viewModel<HomeViewModel>() // Lazy inject ViewModel
private lateinit var homeAdapter: OneAdapter

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_home, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    setupRecyclerView()
    observeImagesLiveData()
}

private fun setupRecyclerView() {
    rvHome.layoutManager = GridLayoutManager(context, 2)
    homeAdapter = OneAdapter()
        .attachItemModule(HomeItem(context!!))
        .attachPagingModule(HomePagingModule(viewModel))
        .attachTo(rvHome)

    homeAdapter.setItems(emptyList())
}

private fun observeImagesLiveData() {
    viewModel.getPicsumImages(1).observe(this, Observer { result ->
        when (result) {
            is Result.Loading -> {
                Timber.e("Loading")
            }

            is Result.Success<*> -> {
                val imagesList = result.data as List<PicsumPhoto>
                homeAdapter.add(imagesList)
            }

            is Result.Error -> {
                Timber.e(result.errorMessage)
            }
        }
    })
}}

ItemModule

class HomeItem(context: Context) : ItemModule<PicsumPhoto>() {

private val displayMetrics = context.resources.displayMetrics
private val columnWidth = displayMetrics.widthPixels / 2

override fun provideModuleConfig() = object : ItemModuleConfig() {
    override fun withLayoutResource() = R.layout.item_home
}

override fun onBind(model: PicsumPhoto, viewBinder: ViewBinder) {
    val mainImage: ImageView = viewBinder.findViewById(R.id.ivMainHomeItem)

    mainImage.apply {
        layoutParams.height = columnWidth
        layoutParams.width = columnWidth
        load(model.download_url)
    }

}}

PagingModule

class HomePagingModule(private val homeViewModel: HomeViewModel) : PagingModule() {

override fun provideModuleConfig() = object : PagingModuleConfig() {
    override fun withLayoutResource() = R.layout.load_more
    override fun withVisibleThreshold() = 3
}

override fun onLoadMore(currentPage: Int) {
    homeViewModel.getPicsumImages(currentPage + 1)
}}
idanatz commented 5 years ago

Hi mehul4795,

When the model does not implement the Diffable interface there is indeed a bug.

After testing some cases of fast scrolling with almost no delay I did not find any issue when the model is implementing the Diffable interface. Please be sure you are implementing the Diffable interface properly and tell me the bug still happens.

mehul4795 commented 5 years ago

Hi, idanatz.

I followed the doc and implemented the Diffable interface but still facing the same problem :(

idanatz commented 5 years ago

Can you please share a minimal project that includes this bug, for me to test?

mehul4795 commented 5 years ago

I am using OneAdapter in a demo project. I have added you as a Collaborator. Please check.

idanatz commented 5 years ago

Thanks, Found the bug, the logic behind the paging was incorrect when fast scrolling and using different layout managers other than Linear. Will be fixed in the next version 💪

mehul4795 commented 5 years ago

That's great. Waiting for the next version. 😍