Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewModels creation is not supported in Preview

I followed the official guide to create viewModel instance and it works perfectly. However, when there is any viewModel in the @composable, Android Studio isn't able to render the preview and with the error code ViewModels creation is not supported in Preview. Anyone got any solution?

P.S. using compose version 1.0.0-alpha06

like image 552
musso Avatar asked Nov 15 '20 06:11

musso


People also ask

Is it possible to create viewmodels in Android Studio?

I followed the official guide to create viewModel instance and it works perfectly. However, when there is any viewModel in the @composable, Android Studio isn't able to render the preview and with the error code ViewModels creation is not supported in Preview.

Can I use a ViewModel in a service?

The ViewModel should be used closely with an Activity or a Fragment, so it's destined to live in the UI layer of your application. Therefore, I don't recommend using the ViewModel in a Service. Create a different class, that would be used in the Service and, if needed, in the ViewModel.

What is the difference between viewmodelstore and viewmodelprovider?

Under the hood a ViewModelStore is used by fragment/activity to store the reference. ... ViewModelProvider is an umbrella object that coordinates Factory and ViewModelStore. Responsibility of this class is identifying the factory and caching viewmodel reference to ViewModelStore.

What is ViewModel in Salesforce?

A ViewModel is implemented as a separate class and contains state values containing the model data and functions that can be called to manage that data. The activity containing the user interface observes the model state values such that any value changes trigger a recomposition.


Video Answer


2 Answers

You could use an approach that looks like this which will show up in the recommended video bellow:

@Composable
fun TestView(
    action: MainActions,
    viewModel: OnboardViewModel = getViewModel()
) {
    TestUI(onClick = viewModel.clickMethod())
}

@Composable
fun TestUI(onClick: () -> Unit) {}

@Preview
@Composable
fun TestUIPreview() {
    MaterialTheme() {
        TestUI(onClick = {})
    }
}

There is a recommendation from google in this video at the selected time: https://youtu.be/0z_dwBGQQWQ?t=573

like image 74
C. Hellmann Avatar answered Oct 09 '22 10:10

C. Hellmann


I had exactly the same problem. The solution was: Extend the ViewModel with an interface

ComposeView:

@Composable
fun MyScreen(myVm: IMyViewModel = MyViewModel()) {
    Text(text = myVm.getTextA())
}


@Preview()
@Composable
fun MyScreenPreview() {
    MyScreen(myVm = MyViewModelPreview())
}

ViewModel:

abstract class IMyViewModel : ViewModel(){
    abstract val dynamicValue: StateFlow<String>
    abstract fun getTextA() : String
}

class MyViewModel : IMyViewModel() {
    private val _dynamicValue: MutableStateFlow<String> = MutableStateFlow("")
    override val dynamicValue: StateFlow<String> = _dynamicValue

    init {
    }

    override fun getTextA(): String {
        return "Details: ${EntityDb.getAllEntities().lastOrNull()?.details}"
    }
}

class MyViewModelPreview(override val dynamicValue: StateFlow<String> =    MutableStateFlow("no data")) : IMyViewModel() {
    override fun getTextA(): String {
        return ""
    }
}
like image 33
Blindsurfer Avatar answered Oct 09 '22 09:10

Blindsurfer