2

I can run Code A in Android Studio, I hope to preview UI when I'm designing, so I added Code B to Code A.

But Code B can't work, why? How can I fix it?

Code A

class MainActivity : ComponentActivity() {

    private val handleMeter by viewModels<HandleMeter>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            SoundMeterTheme {       
                Surface(color = MaterialTheme.colors.background) {
                    Greeting(handleMeter)
                }
            }
        }
    }
}

@Composable
fun Greeting(handleMeter: HandleMeter) {
  ...
}

Code B

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    SoundMeterTheme {
        val handleMeter by viewModels<HandleMeter>()
        Greeting(handleMeter)
    }
}
HelloCW
  • 843
  • 22
  • 125
  • 310
  • You probably see this in logs: java.lang.IllegalStateException: ViewModels creation is not supported in Preview. You neen to pass viewmodel's methods and properties (or fake empty copies of) to your composable instead of viewmodel itsef. – bylazy Jan 26 '22 at 14:08
  • Thanks! How can I to pass viewmodel's methods and properties (or fake empty copies of) ? – HelloCW Jan 27 '22 at 00:18
  • Its called state hoisting, look here: https://stackoverflow.com/questions/69689843/jetpack-compose-state-hoisting-previews-and-viewmodels-best-practices – bylazy Jan 27 '22 at 06:07

2 Answers2

2

Unfortunately, you can't. Preview does not support creating ViewModels and NavHost yet, for our bad. But what you can do instead is to use a fake data or a static data into ui, until the design finish and when you are ready to actually run it, replace the static data with the view model data.

Mustafa Ibrahim
  • 557
  • 3
  • 8
0

You can use dagger and hilt to inject the view model constructor and then call up the hilt view model in the preview e.g.

@HiltViewModel
class DataFieldsViewModel @Inject constructor(
) : ViewModel() {

Then in your preview code for your composable

@Preview(showBackground = true)
@Composable
fun PreviewDataFieldsScreen() {
    DataFieldsScreen(
        navController = rememberNavController(),
        viewModel = hiltViewModel()
    )
}
J_Orotayo
  • 45
  • 4