В viewModel:
Код: Выделить всё
class DoctorViewModel(private val repository: DoctorRepository) : ViewModel() {
private val _doctors = mutableStateOf(emptyList())
private val _doctorsFlow = MutableStateFlow
>(PagingData.empty())
val doctorsFlow: StateFlow get() = _doctorsFlow
var doctorSpecialty = mutableStateOf("")
var userLatitude = mutableStateOf(0.0)
var userLongitude = mutableStateOf(0.0)
var radius = mutableStateOf(25000)
var currentPage by mutableStateOf(1) // Hold current page in ViewModel
suspend fun getDoctorsBySpecialty()
{
val query = getOverpassQueryForSpecialty(doctorSpecialty.value, userLatitude.value, userLongitude.value , radius.value) // adjust radius and query as needed
_doctors.value = repository.fetchAllDoctors(query)
}
// PagingSource for local pagination over the loaded doctors
fun getDoctorsPaged(page: Int): Flow {
return Pager(
config = PagingConfig(
pageSize = 5, // Adjust page size as needed
enablePlaceholders = false
),
pagingSourceFactory = { DoctorsLocalPagingSource(_doctors.value, page) } // Pass page
).flow.cachedIn(viewModelScope)
}
Код: Выделить всё
class DoctorsLocalPagingSource(private val doctors: List, private val page: Int) : PagingSource() {
override suspend fun load(params: LoadParams): LoadResult {
val pageSize = 5
val page = params.key ?: 1
val fromIndex = (page - 1) * pageSize
val toIndex = minOf(fromIndex + pageSize, doctors.size)
println("Loading page $page with fromIndex $fromIndex to toIndex $toIndex")
Код: Выделить всё
return if (fromIndex < doctors.size) {
val pageItems = doctors.subList(fromIndex, toIndex)
LoadResult.Page(
data = pageItems,
prevKey = if (page == 1) null else page - 1,
nextKey = if (toIndex < doctors.size) page + 1 else null
)
} else {
LoadResult.Page(
data = emptyList(),
prevKey = if (page == 1) null else page - 1,
nextKey = null
)
}
}
override fun getRefreshKey(state: PagingState): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}
}
Код: Выделить всё
@Composable
fun DoctorScreen(viewModel: DoctorViewModel) {
// Use remember to keep the current page state stable
var currentPage by remember { mutableStateOf(1) }
var isDoctorsLoaded by remember { mutableStateOf(false) }
// StateFlow to hold PagingData and initialize with an empty PagingData
val doctorsPagingFlow = remember { MutableStateFlow(PagingData.empty()) }
var lazyPagingItems : LazyPagingItems = doctorsPagingFlow.asStateFlow().collectAsLazyPagingItems()
// State variable to hold lazyPagingItems, initializing with an empty list
var column_items = remember {
mutableStateOf(lazyPagingItems)
}
// Trigger fetch when current page changes
LaunchedEffect(currentPage) {
viewModel.getDoctorsBySpecialty()
isDoctorsLoaded = true
}
// Initialize lazyPagingItems only when doctors are loaded
if (isDoctorsLoaded)
lazyPagingItems = viewModel.getDoctorsPaged(currentPage).collectAsLazyPagingItems()
// Create a derived state that updates whenever lazyPagingItems changes
// val columnItems by remember {
// derivedStateOf { lazyPagingItems }
// }
LazyVerticalGrid(columns = GridCells.Fixed(2)) {
// Check for item count before rendering
items(count = lazyPagingItems.itemCount,
key = lazyPagingItems.itemKey { it.id },
contentType = lazyPagingItems.itemContentType { "contentType" }
) { index ->
var doctorItem = lazyPagingItems[index]
if (doctorItem != null) {
DoctorListItem(doctorItem)
}
}
// Pagination loading indicators
lazyPagingItems?.apply {
when {
loadState.refresh is LoadState.Loading -> {
item { CircularProgressIndicator() }
}
loadState.append is LoadState.Loading -> {
item { CircularProgressIndicator() }
}
}
}
}
// Pagination controls
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
Button(
onClick = {
if (currentPage > 1) {
currentPage--
}
},
enabled = currentPage > 1
) {
Text("Previous")
}
Text("Page $currentPage")
Button(
onClick = {
currentPage++
},
enabled = lazyPagingItems.itemCount >= 5 // Adjust based on your page size
) {
Text("Next")
}
}
}
Спасибо за ваш вклад.
Подробнее здесь: https://stackoverflow.com/questions/791 ... infinitely