Android ContentResolver.query Image by Album Load Data via Compose Paging

December 14, 2021

Refer to Gallery class to query images by album with paging.

Refer to Jetpack Compose Paging Sample.

class LocalImageRepository(private val gallery: Gallery, val pageSize: Int) {
    suspend fun getItems(albumId: String, page: Int): List<Gallery.LocalImage> {
        return withContext(Dispatchers.IO) {
            // if (page > 1) delay(2000)
            gallery.findLocalImagesByAlbum(albumId = albumId, page = page, pageSize = pageSize)
        }
    }
}
class LocalImageSource(private val repo: LocalImageRepository, val albumId: String) : PagingSource<Int, Gallery.LocalImage>() {
    override fun getRefreshKey(state: PagingState<Int, Gallery.LocalImage>): Int? {
        return state.anchorPosition
    }

    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Gallery.LocalImage> {
        val page = params.key ?: 1

        return try {
            val items = repo.getItems(albumId, page)
            val count = items.size

            LoadResult.Page(
                data = items,
                prevKey = if (page == 1) null else page - 1,
                // nextKey = if (page * repo.pageSize < repo.totalCount) page + 1 else null,
                nextKey = if (count < repo.pageSize) null else page + 1
            )
            // }
        }
        catch (e: Exception) {
            LoadResult.Error(e)
        }
    }
}

ViewModel function

class SelectPhotoViewModel(private val gallery: Gallery, savedStateHandle: SavedStateHandle) : ViewModel() {
    
    val albumId = savedStateHandle.get<String>("albumId")

    val imageFlow = let {
        val repo = LocalImageRepository(gallery = gallery, pageSize = 10)

        Pager(PagingConfig(pageSize = repo.pageSize)) {
            LocalImageSource(repo = repo, albumId = albumId, date = date)
        }.flow
    }
}

Usage

@Composable
fun SelectPhotoScreen(viewModel: SelectPhotoViewModel = viewModel()) {
    val lazyImages = viewModel.imageFlow.collectAsLazyPagingItems()

    LazyColumn() {
        items(lazyImages) { image ->
            PhotoItem(data = image.uri)
        }
    }
}

NOTE: PhotoItem from Jetpack Compose Load Image With Coil.

This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.