I've a composable called ParentScreen
and a ViewModel
named ParentViewModel
. Inside the ParentViewModel
, I am collecting a value from my repo.
class MyRepo @Inject constructor() {
fun getParentData() = System.currentTimeMillis().toString() // some dummy value
}
@HiltViewModel
class ParentViewModel @Inject constructor(
myRepo: MyRepo
) : ViewModel() {
private val _parentData = MutableStateFlow("")
val parentData = _parentData.asStateFlow()
init {
val realData = myRepo.getParentData()
_parentData.value = realData
}
}
@Composable
fun ParentScreen(
parentViewModel: ParentViewModel = hiltViewModel()
) {
val parentData by parentViewModel.parentData.collectAsState()
ChildWidget(parentData = parentData)
}
Inside the ParentScreen
composable, I have a ChildWidget
composable and it has its own ViewModel
named ChildViewModel
.
@HiltViewModel
class ChildViewModel @AssistedInject constructor(
@Assisted val parentData: String
) : ViewModel() {
@AssistedFactory
interface ChildViewModelFactory {
fun create(parentData: String): ChildViewModel
}
init {
Timber.d("Child says data is $parentData ")
}
}
@Composable
fun ChildWidget(
parentData: String,
childViewModel: ChildViewModel = hiltViewModel() // How do I supply assisted injection factory here?
) {
// Code omitted
}
Now, I want to get parentData
inside ChildViewModel
's constructor.
Questions
- How do I supply
ChildViewModelFactory
to Navigation Compose'shiltViewModel
method? - If that's not possible, what would be the most suitable method to inject an object from the parent composable to the child composable's
ViewModel
? How about creating alateinit
property andinit
method like below?
@HiltViewModel
class ChildViewModel @Inject constructor(
) : ViewModel() {
lateinit var parentData: Long
fun init(parentData: Long){
if(this::parentData.isInitialized) return
this.parentData = parentData
}
}