Reputation: 4080
We know that the following way to create an instance is very good, you can enjoy life cycle management. And the instances created in an ViewModel are the same.
But if you want to create two instances on one page, how to create it?
fun Following(viewModel: FollowViewModel = viewModel()) {
}
Upvotes: 5
Views: 2777
Reputation: 14449
If you use Dagger Hilt, the support to the key
is added via the AndroidX artifact androidx.hilt:hilt-navigation-compose
.
Alternatively you can create yourself this inline function:
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.HiltViewModelFactory
import androidx.lifecycle.HasDefaultViewModelProviderFactory
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.viewModel
/**
* Returns an existing
* [HiltViewModel](https://dagger.dev/api/latest/dagger/hilt/android/lifecycle/HiltViewModel)
* -annotated [ViewModel] or creates a new one scoped to the current navigation graph present on
* the {@link NavController} back stack.
*
* If no navigation graph is currently present then the current scope will be used, usually, a
* fragment or an activity.
*
* @sample androidx.hilt.navigation.compose.samples.NavComposable
* @sample androidx.hilt.navigation.compose.samples.NestedNavComposable
*/
@Composable
inline fun <reified VM : ViewModel> hiltViewModel(
viewModelStoreOwner: ViewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
"No ViewModelStoreOwner was provided via LocalViewModelStoreOwner"
},
key: String? = null
): VM {
val factory = createHiltViewModelFactory(viewModelStoreOwner)
return viewModel(viewModelStoreOwner, key, factory = factory)
}
@Composable
@PublishedApi
internal fun createHiltViewModelFactory(
viewModelStoreOwner: ViewModelStoreOwner
): ViewModelProvider.Factory? = if (viewModelStoreOwner is HasDefaultViewModelProviderFactory) {
HiltViewModelFactory(
context = LocalContext.current,
delegateFactory = viewModelStoreOwner.defaultViewModelProviderFactory
)
} else {
// Use the default factory provided by the ViewModelStoreOwner
// and assume it is an @AndroidEntryPoint annotated fragment or activity
null
}
Upvotes: 0
Reputation: 88222
You can use key
argument which is used to identify the ViewModel
:
val firstViewModel = viewModel<FollowViewModel>(key = "first")
val secondViewModel = viewModel<FollowViewModel>(key = "second")
p.s. If you are using Hilt, hiltViewModel
does not yet support keys, you can star this feature request for updates, and check out hack in this answer for now.
Upvotes: 14