I request api call from developer.themoviedb.org with page parameter, i want to get another page when scroll reach the bottom.
Is this best case? Whats your suggestions for optimize code?
Here is my viewModel;
@HiltViewModel
class PopularMoviesViewModel @Inject constructor(
private val contentRepository: ContentRepository
) : ViewModel() {
private val _state = mutableStateOf<ScreenState<List<Movie>>>(ScreenState.Loading)
val state: State<ScreenState<List<Movie>>> get() = _state
private val movieList: MutableList<Movie> = mutableListOf()
init {
getPopularMovies(1)
}
fun getPopularMovies(page: Int) = viewModelScope.launch {
println("getPopularMovies Runned")
contentRepository.getPopularMovies(page).collect { response ->
when (response) {
is NetworkResponseState.Error -> _state.value =
ScreenState.Error(response.exception.message.toString())
is NetworkResponseState.Loading -> {
_state.value = ScreenState.Loading
}
is NetworkResponseState.Success -> {
println("getPopularMovies Success")
movieList.addAll(response.result)
_state.value = ScreenState.Success(movieList)
}
}
}
}
}
This model get first page on init, after get another page when scroll reached bottom
Here is my screen;
@Composable
fun PopularMoviesScreen(
viewModel: PopularMoviesViewModel = hiltViewModel(),
onBack: () -> Unit
) {
var list by remember { mutableStateOf(listOf<Movie>()) }
var pageCounter by remember { mutableIntStateOf(1) }
val listState = rememberLazyGridState()
LaunchedEffect(key1 = Unit) {
listState.scrollToItem(20 * (pageCounter - 1))
}
when (val popularMoviesState = viewModel.state.value) {
is ScreenState.Success -> {
list = popularMoviesState.uiData
PopularMoviesSuccessContent(
movieList = popularMoviesState.uiData,
onBack = onBack,
onSearch = {
pageCounter++
viewModel.getPopularMovies(pageCounter)
},
state = listState
)
}
is ScreenState.Loading -> {
PopularMoviesLoadingContent(onBack = onBack, list, state = listState)
}
is ScreenState.Error -> {
ErrorScreen(
message = popularMoviesState.message,
)
}
}
}
@Composable
fun PopularMoviesSuccessContent(
movieList: List<Movie>,
onBack: () -> Unit,
onSearch: () -> Unit,
state: LazyGridState
) {
Column {
LazyVerticalGrid(
state = state,
columns = GridCells.Fixed(2),
modifier = Modifier
.fillMaxSize()
.padding(8.dp),
content = {
item(span = { GridItemSpan(2) }) {
CustomText(
text = "Popular Movies",
fontFamilyID = R.font.poppins_semi_bold,
fontSize = 24.sp,
color = MaterialTheme.colorScheme.primary,
modifier = Modifier
.fillMaxWidth()
.padding(top = 16.dp, start = 8.dp, bottom = 8.dp)
)
}
items(movieList.size) {
TrendContentItem(
movie = movieList[it]
)
}
item {
LaunchedEffect(key1 = Unit) {
onSearch()
}
}
})
}
}
@Composable
fun PopularMoviesLoadingContent(onBack: () -> Unit, list: List<Movie>, state: LazyGridState) {
Column {
LazyVerticalGrid(
columns = GridCells.Fixed(2),
state = state,
modifier = Modifier
.fillMaxSize()
.padding(8.dp),
content = {
item(span = { GridItemSpan(2) }) {
CustomText(
text = "Popular Movies",
fontFamilyID = R.font.poppins_semi_bold,
fontSize = 24.sp,
color = MaterialTheme.colorScheme.primary,
modifier = Modifier
.fillMaxWidth()
.padding(top = 16.dp, start = 8.dp, bottom = 8.dp)
)
}
items(list.size) {
TrendContentItem(
movie = list[it]
)
}
items(6) {
LoadingContentItems()
}
})
}
}