问题描述
我想在HomeScreenPreview
预览函数中显示HomeScreen
组合函数的预览。但是,由于我遇到了以下错误,所以无法实现:
java.lang.IllegalStateException: ViewModels creation is not supported in Preview
at androidx.compose.ui.tooling.ComposeViewAdapter$FakeViewModelStoreOwner$1.getViewModelStore(ComposeViewAdapter.kt:709)
at androidx.lifecycle.ViewModelProvider.<init>(ViewModelProvider.kt:105)
at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:82)
at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:72)
at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreen(HomeScreen.kt:53)
at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreenPreview(HomeScreen.kt:43)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
...
我的代码
这是我的HomeScreen
代码:
@Composable
fun HomeScreen(
viewModel: HomeViewModel = hiltViewModel(),
navigateToDetailsAction: () -> Unit,
openCardDetailsAction: (Int) -> Unit
) {
val cities = viewModel.cities.observeAsState(listOf())
Scaffold(
topBar = { HomeAppBar() },
floatingActionButton = { HomeFab(navigateToDetailsAction) }
) {
HomeContent(cities) { id -> openCardDetailsAction(id) }
}
}
这是我的预览功能的代码:
@Preview
@Composable
private fun HomeScreenPreview() {
HomeScreen(navigateToDetailsAction = {}, openCardDetailsAction = {})
}
我的视图模型:
@HiltViewModel
class HomeViewModel @Inject constructor(repository: CityRepository) : ViewModel() {
val cities: LiveData<List<City>> = repository.allCities.asLiveData()
}
代码库:
@ViewModelScoped
class CityRepository @Inject constructor(appDatabase: AppDatabase) {
private val dao by lazy { appDatabase.getCityDao() }
val allCities by lazy { dao.getAllCities() }
suspend fun addCity(city: City) = dao.insert(city)
suspend fun updateCity(city: City) = dao.update(city)
suspend fun deleteCity(city: City) = dao.delete(city)
suspend fun getCityById(id: Int) = dao.getCityById(id)
}
应用程序数据库:
@Database(entities = [City::class], version = 2, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun getCityDao() : CityDao
}
我的失败尝试
我认为可能是因为将视图模型作为 HomeScreen
的默认参数传递导致了问题,所以我决定这样做:
@Composable
fun HomeScreen(
navigateToDetailsAction: () -> Unit,
openCardDetailsAction: (Int) -> Unit
) {
val viewModel: HomeViewModel = hiltViewModel()
val cities = viewModel.cities.observeAsState(listOf())
Scaffold(
topBar = { HomeAppBar() },
floatingActionButton = { HomeFab(navigateToDetailsAction) }
) {
HomeContent(cities) { id -> openCardDetailsAction(id) }
}
}
但它仍然不起作用(我一直得到相同的错误),而且对于测试也不好,因为它会阻止我使用模拟的视图模型来测试HomeScreen
。
cities
传递到HomeScreen()
(在第二个代码片段中)并消除对视图模型的依赖。 - CommonsWareHomeScreen
与HomeViewModel
有更多的依赖关系,那么这可能会成为一个问题。或者,理想情况下,一个屏幕不需要担心与之“相关”的视图模型? - Pierre Vieira