Nick
09/15/2023, 4:42 PMLazyColumn (or a regular Column, since I know that the number of items is limited to less than 10) that has a number of `Card`s in it, each of which has their own view model instance (of the same view model class, CardViewModel, below). I’m seeing an issue where data in one card seems to be duplicated in another. In trying to chase that down, I started logging in the init() and onCleared() and noticed that those are called when the `Card`s are scrolled on-/off-screen.
My understanding is that the viewmodel should be retained for the life of the scope (which is a NavBackStackEntry in this case)--I wouldn’t expect to see onCleared() called while the screen is still in scope. Is the pattern in the threads above still considered best practices for this situation? If so, is there a clean way to manage `factory`s being passed around?
Please tell me if I can provide any more information--and thanks so much for your help!Zach Klippenstein (he/him) [MOD]
09/15/2023, 6:44 PMNick
09/15/2023, 6:45 PM@Composable
private fun cardViewModel(serialNumber: String): CardViewModel {
val factory = EntryPointAccessors.fromActivity(
LocalContext.current as Activity,
MainActivity.ViewModelFactoryProvider::class.java
).cardViewModelFactory()
return viewModel(
factory = CardViewModel.provideFactory(
factory,
serialNumber,
),
key = serialNumber
)
}
@Composable
fun CardComponent(
serialNumber: String
) {
val viewModel = cardViewModel(serialNumber = serialNumber)
CardView(viewModel, serialNumber)
}
class CardViewModel @AssistedInject constructor(
@Assisted private val serialNumber: String,
private val navigationController: NavigationController,
@Assisted private val savedStateHandle: SavedStateHandle,
) : ViewModel() {
@AssistedFactory
interface Factory {
fun create(
serialNumber: String,
savedStateHandle: SavedStateHandle,
): DeviceCardViewModel
}
@Suppress("UNCHECKED_CAST")
companion object {
fun provideFactory(
assistedFactory: Factory,
serialNumber: String,
): AbstractSavedStateViewModelFactory = object : AbstractSavedStateViewModelFactory() {
override fun <T : ViewModel> create(
key: String,
modelClass: Class<T>,
handle: SavedStateHandle
): T {
return assistedFactory.create(serialNumber, handle) as T
}
}