xlog
xlog

Reputation: 103

Android Compose MVVM - How to reference a viewModel object in a Composable function that doesn't take arguments?

How would the @Composable ContentFeed() function access the viewModel which was created in the Activity? Dependency injection? Or is that a wrong way of doing things here? The viewModel should always have only have one instance.

// MainActivity.kt
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val viewModel by viewModels<MainViewModel>()
        setContent {
        PracticeTheme {
            // A surface container using the 'background' color from the theme
            Surface(color = MaterialTheme.colors.background) {
                PulseApp(viewModel)
            }
        }
    }
}

// TabItem.kt
typealias ComposableFun = @Composable () -> Unit

sealed class TabItem(var icon: Int, var title: String, var content: ComposableFun) {
    object Feed : TabItem(R.drawable.ic_baseline_view_list_24, "Feed", { ContentFeed() })
}

// Content.kt
@Composable
fun ContentFeed() {
    // I need viewModel created in MainActivity.kt here
}

Upvotes: 2

Views: 3039

Answers (1)

Phil Dukhov
Phil Dukhov

Reputation: 87774

In any composable you can use viewModel<YourClassHere>():

Returns an existing ViewModel or creates a new one in the given owner (usually, a fragment or an activity), defaulting to the owner provided by LocalViewModelStoreOwner.

The only exception in Compose for now, when it's not bind to activity/fragment, is when you're using Compose Navigation. In this case the store owner is bind to each route, see this and this answers on how you can share store owners between routes.

Check out more about view models Compose in documentation.

Upvotes: 5

Related Questions