[英]Android jetpack compose observing a livedata
I have question regarding using observeAsState() to automatically populate a composable list view.我有关于使用observeAsState()自动填充可组合列表视图的问题。
My composable looks like this我的组合看起来像这样
@Composable
fun getTopMovies() {
val topMovies by movieListViewModel.getTopMovies().observeAsState()
when (topMovies?.status) {
Status.Error -> Text("error")
Status.Loading -> {
Log.d("JJJ", "Loading ")
Text(text = "Loading")
}
Status.Success -> createMovieItemView(topMovies?.data?.results.orEmpty())
}
}
This uses MVVM to do a network call to fetch some list of data and return it it back as a livedata.这使用 MVVM 进行网络调用以获取一些数据列表并将其作为实时数据返回。
The issue i am having is that it seems stuck on a infinit loop.我遇到的问题是它似乎卡在无限循环中。 If i dont use observeeAsState and just use the normal none composable way ie:
如果我不使用observeeAsState而只使用正常的不可组合方式,即:
movieListViewModel.getTopMovies().observe(viewLifecycleOwner, Observer { ...}
it works as expected and executes and ends once a error or a success is returned from the repository/domain layer.一旦从存储库/域层返回错误或成功,它就会按预期工作并执行并结束。
This is the createMovieItemView below:这是下面的 createMovieItemView:
@Composable
private fun createMovieItemView(movieList: List<MovieItem>) {
LazyColumnFor(items = movieList, itemContent = { movieItem ->
MovieListItem(MovieItemData(movieItem.posterPath.orEmpty(),
movieItem.title.orEmpty(),
movieItem.releaseDate.orEmpty(),
"some genra", ""), picasso)
})
}
to automatically populate a composable list view.自动填充可组合列表视图。
My composable looks like this我的组合看起来像这样
@Composable
fun getTopMovies() {
val topMovies by movieListViewModel.getTopMovies().observeAsState()
when (topMovies?.status) {
Status.Error -> Text("error")
Status.Loading -> {
Log.d("JJJ", "Loading ")
Text(text = "Loading")
}
Status.Success -> createMovieItemView(topMovies?.data?.results.orEmpty())
}
}
This uses MVVM , to do a network call to fetch some list of data and then returns a livedata.这使用MVVM进行网络调用以获取一些数据列表,然后返回一个实时数据。
Issue seems to be, it stuck in a infinit loop.问题似乎是,它陷入了无限循环。 If i dont use observeeAsState and just use the normal none composable way ie movieListViewModel.getTopMovies().observe(viewLifecycleOwner, Observer { it works as expected, executes and ends once an error or a success is returned from the repository/domain layer.
如果我不使用observeeAsState 而只是使用正常的非可组合方式,即movieListViewModel.getTopMovies().observe(viewLifecycleOwner, Observer { 它按预期工作,一旦从存储库/域层返回错误或成功,它就会执行并结束。
I had a similar problem and I solved by wrapping getTopMovies
inside a LaunchedEffect
block and I end up with something like this:我有一个类似的问题,我通过将
getTopMovies
包装在LaunchedEffect
块中解决了,我最终得到了这样的结果:
@Composable
fun MoviesScreen(onTimeout: () -> Unit) {
val topMovies by viewModel.topMovies.observeAsState()
LaunchedEffect(true) {
movieListViewModel.getTopMovies().observeAsState()
}
}
Whereas the viewModel would be something like:而 viewModel 将类似于:
class MoviesViewModel(): ViewModel {
var _topMovies: MutableLiveData<List<Movies>> = mutableLiveDataOf(listOf())
val topMovies: LiveData<List<Movies>>
fun getTopMovies(){
_topMovies.postValue(repository.getTopMovies())
}
}
Note this is pseudo-code to describe the solution.请注意,这是描述解决方案的伪代码。 Which is inspired on rememberUpdatedState extample
灵感来自于rememberUpdatedState 示例
If getTopMovies
uses co-routines, it has side-effects, therefore LaunchedEffect
is needed because Composables should be side-effect free as it is described at Side-effects in Compose .如果
getTopMovies
使用协程,则它有副作用,因此需要LaunchedEffect
,因为Composables 应该是无副作用的,如 Compose 中的副作用中所述。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.