rajesh
11/25/2021, 10:33 AMProfileViewModel
) that has a function that fetch posts (paging data) of given user. I've 2 composables namely ProfileView
and DetailedPostView
I need to use same function to load posts with cached value in viewmodel, but when I navigate to detailed screen, it re-fetch the data instead of cached value. How to avoid it? code is in thread.rajesh
11/25/2021, 10:33 AMclass ProfileViewModel @Inject constructor(private val profileRepository: ProfileRepository) : ViewModel() {
fun getUserPosts(userId: Long): Flow<PagingData<Post>> =
profileRepository
.getUserPosts(userId)
.cachedIn(viewModelScope)
}
@Composable
fun ProfileScreen(
navController: NavController,
userId: Long,
profileViewModel: ProfileViewModel,
) {
val posts = remember(profileViewModel) { profileViewModel.getUserPosts(userId) }.collectAsLazyPagingItems()
// Navigate to PostDetailsScreen
}
@Composable
fun PostDetailsScreen(
navController: NavController,
userId: Long,
profileViewModel: ProfileViewModel
) {
val posts = remember(profileViewModel) { profileViewModel.getUserPosts(userId) }.collectAsLazyPagingItems()
}
@Composable
fun Navigation(navController: NavHostController) {
composable(
route = Screens.PostDetails.route + "/{userId}",
arguments = listOf(navArgument(name = "userId") { type = NavType.LongType })
) { backStackEntry ->
val profileViewModel = hiltViewModel<ProfileViewModel>()
PostDetailsScreen(
navController = navController,
userId = backStackEntry.arguments?.getLong("userId"),
profileViewModel = profileViewModel
)
}
}
rajesh
11/25/2021, 10:34 AMRegardless of whether you use viewModel() or with Hilt hiltViewModel() to retrieve your ViewModel, they both will call onCleared() when the NavHost finishes transitioning to a different route
Abhinav Suthar
11/25/2021, 1:38 PMAbhinav Suthar
11/25/2021, 1:38 PM@MainThread
inline fun <reified VM : ViewModel> Fragment.scopedViewModel(
@IdRes navId: Int,
noinline factoryProducer: (() -> ViewModelProvider.Factory)? = null
): Lazy<VM> {
val backStackEntry by lazy {
try {
findNavController().getBackStackEntry(navId)
} catch (e: Exception) {
this
}
}
val storeProducer: () -> ViewModelStore = {
backStackEntry.viewModelStore
}
return createViewModelLazy(VM::class, storeProducer, {
factoryProducer?.invoke() ?: backStackEntry.defaultViewModelProviderFactory
})
}
rajesh
11/25/2021, 1:54 PMStylianos Gakis
11/25/2021, 2:06 PMrajesh
11/25/2021, 3:26 PMnavigation(
startDestination = Screens.Home.route,
route = Screens.UserProfile.route
) {
composable(
route = Screens.PostList.route + "/{userId}/{index}",
arguments = listOf(
navArgument(name = "userId") {
type = NavType.LongType
},
navArgument(name = "index") {
type = NavType.IntType
}
)
) { backStackEntry ->
val parentEntry =
remember { navController.getBackStackEntry(Screens.UserProfile.route) }
val userProfileVM = hiltViewModel<UserProfileViewModel>(parentEntry)
PostListScreen(
navController = navController,
userId = backStackEntry.arguments?.getLong("userId"),
index = backStackEntry.arguments?.getInt("index"),
homeViewModel = homeViewModel,
userProfileViewModel = userProfileVM
)
}
}
Stylianos Gakis
11/25/2021, 5:43 PMgetUserPosts
on both compostables, doing so on the same VM instance doesn't change that fact. I'm not familiar with the paging library, but there should be a way to just observe the incoming data instead of also triggering the fetching of themTash
11/28/2021, 8:33 PMTash
11/28/2021, 8:34 PMrajesh
12/09/2024, 5:05 AM