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
}
}