Search code examples
android-jetpack-composeandroid-roomandroid-paging-3jetpack-compose-navigation

An instance of PagingSource was re-used when Pager expected to create a new [Compose+Paging3]


How to invalidate PagingSource when new items added/updated?

How to observe any changes to room database records?

Agenda:

I was trying to add new records in every 10 secs and wants to reflect those changes into UI.

but failing to implement it.

Errors:

java.lang.IllegalStateException: An instance of PagingSource was re-used when Pager expected to create a new
                                                                                                    instance. Ensure that the pagingSourceFactory passed to Pager always returns a
                                                                                                    new instance of PagingSource.

Kotlin Class

class ArticlePagedUseCase @Inject constructor(
    private val repository: ArticleRepository
) {

    operator fun invoke(): Flow<PagingData<ArticleEntity>> {
        Log.d("GoogleIO","Invalidate Paging 3")
        return Pager(
            config = PagingConfig(
                pageSize = 20,
                prefetchDistance = 40
            ),
            pagingSourceFactory = {
                repository.articlesPaged
            }
        ).flow
    }

    suspend fun addArticle(articleEntity: ArticleEntity) {
        delay(1000)
        repository.addArticle(articleEntity)
    }

}

Dao

@Dao
interface ArticleDao {

    @Query("SELECT * FROM article_entity")
    fun getAllArticlesPaged() : PagingSource<Int, ArticleEntity>

    @Insert
    suspend fun addArticle(articleEntity: ArticleEntity)
}

Paging 3 Outcome with new changes reflection on UI everytime database updated.


Solution

  • I solved this by implementing below condition

    @Composable
    fun ArticleContent(viewModel: MainViewModel = hiltViewModel()) {
    
    val lazyArticleItems = viewModel.articlesFlows.collectAsLazyPagingItems()
    
    if (lazyArticleItems.loadState.refresh is LoadState.Loading && lazyArticleItems.itemCount < 1) {
        Log.d("GoogleIO", "LazyArticleIsLoading")
    } else {
        Log.d("GoogleIO", "LazyArticleIsLoaded :: :: ")
        LazyColumn {
            items(
                count = lazyArticleItems.itemCount
            ) { index: Int ->
                ArticleItem(lazyArticleItems[index]!!)
            }
        }
    }
    

    }