Search code examples
androidkotlinandroid-jetpack-composeviewmodel

How to access a viewmodel as a function argument?


Android Studio shows an error:

Unresolved reference: abc

I tried changing the view model name and how it is instantiated, e.g. val myViewModel5 by viewModels<MyViewModel>()

class simpleViewModel : ViewModel() {
    val abc = 1;
}

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val myViewModel by viewModels<simpleViewModel>()
        setContent {
            MyApplicationTheme {
                // A surface container using the 'background' color from the
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    app(ViewModelProvider(this).get(simpleViewModel::class.java))
                }
            }
        }
    }
}

@Composable
fun app(v: ViewModel) {
    Text(v.abc)
}

But it doesn't matter what I do, I can't use the member of the view model. Shoud I use a single functon for the whole app?


Solution

  • You specified the wrong type for v. It should be simpleViewModel instead of ViewModel.

    The convention is to name all types with an uppercase first letter though:

    class SimpleViewModel : ViewModel() {
        val abc = 1
    }
    

    Also, in your MainActivity you already have the view model instance myViewModel, so you don't need to jump through hoops with ViewModelProvider(this).get(simpleViewModel::class.java). Also, you shouldn't pass view model instances around, just pass what is needed:

    MyApplicationTheme {
        // A surface container using the 'background' color from the
        Surface(
            modifier = Modifier.fillMaxSize(),
            color = MaterialTheme.colorScheme.background,
        ) {
            App(myViewModel.abc)
        }
    }
    

    By convention, composables also start with an uppercase letter:

    @Composable
    fun App(abc: Int) {
        Text("$abc")
    }