Я пытаюсь создать простое приложение для листинга и для извлечения данных из URL-адреса я использую retrofit2. Затем я сохраняю объект MutableLiveData<Resource>. Как я могу перечислить результаты модификации 2 в LazyColumn?
Мой составной:
@ExperimentalAnimationApi
@Composable
fun CarsScreen(
viewModel: CarListViewModel = hiltViewModel()
){
viewModel.getCarsFromAPI()
val carsLiveData = viewModel.carsLiveData.observeAsState()
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
){
GreetingSection()
}
LazyColumn(
modifier = Modifier.fillMaxSize(),
) {
itemsIndexed( ){
//TODO
}
}
}
Модель просмотра:
@HiltViewModel
class CarListViewModel @Inject constructor(
private val carRepository: CarRepository
): ViewModel() {
val carsLiveData:MutableLiveData<Resource<CarsResponse>> = MutableLiveData()
fun getCarsFromAPI() = viewModelScope.launch {
carsLiveData.postValue(Resource.Loading())
val response = carRepository.getCarsFromAPI()
carsLiveData.postValue(handleCarResponse(response))
}
private fun handleCarResponse(response: Response<CarsResponse>) : Resource<CarsResponse> {
if (response.isSuccessful){
response.body()?.let{resultResponse ->
return Resource.Success(resultResponse)
}
}
return Resource.Error(response.message())
}
}
observeAsState
не возвращает LiveData
; он возвращает данные, содержащиеся в LiveData
, которые вы наблюдаете.
Всякий раз, когда значение этого LiveData
изменяется, запускается перекомпоновка, и вы получаете новое значение.
Измените название свойства carsLiveData
на просто cars
. Вы можете использовать это непосредственно как элементы в вашем LazyColumn
.
Еще одно замечание: вы вызываете viewModel.getCarsFromAPI()
внутри компонуемого CarsScreen
каждый раз, когда он перекомпоновывается. Вы, наверное, не хотите этого делать.
Если вы хотите получить список только один раз, вы можете использовать LaunchedEffect
внутри CarsScreen
, например:
// Copyright 2023 Google LLC.
// SPDX-License-Identifier: Apache-2.0
@Composable
fun CarsScreen(...) {
LaunchedEffect(Unit) {
viewModel.getCarsFromAPI()
}
...
}
Если вы хотите обновить этот список, передайте некоторое состояние в LaunchedEffect
вместо Unit — всякий раз, когда это состояние изменяется, LaunchedEffect
будет отменен (если в данный момент запущен) и перезапущен.