【问题标题】:Android Compose MVVM multi network callAndroid Compose MVVM 多网络调用
【发布时间】:2021-12-15 19:29:55
【问题描述】:

我通过改编我的一个干净的架构应用程序开始使用 Jetpack Compose。我用这个撰写功能创建了一个底部导航栏:

@Composable
fun Navigation(navController: NavHostController){
    NavHost(navController, startDestination = NavigationItem.Planes.route) {
        composable(NavigationItem.Planes.route) {
            PlanesScreen(hiltViewModel())
        }
        composable(NavigationItem.Weather.route) {
            WeatherScreen()
        }
        composable(NavigationItem.More.route) {
            MoreScreen()
        }
    }

}

在我的PlanesScreen 中,我使用 Hilt 方法将以下ViewModel 传递给它:

@HiltViewModel
class PlanesViewModel @Inject constructor(private val planeInfoUseCase: PlaneInfoUseCase) : ViewModel() {

    fun planeInfo() : LiveData<UiResponse<ArrayList<PlaneInfo>>> {
        return planeInfoUseCase.execute().toUiResponse().flowAsLiveData(Dispatchers.IO)
    }    
}

useCase 返回一个Flow,我将其转换为UiResponse 以表示我视图的不同状态:

fun <T> Flow<T>.toUiResponse() : Flow<UiResponse<T>>{
    return this.map<T, UiResponse<T>> { UiResponse.Success(it) }
        .onStart { emit(UiResponse.Loading()) }
        .catch {
            val t : Throwable = it
            emit(UiResponse.Error(it))
        }
}

PlaneScreen 屏幕包含一个可组合的方法,可以不受任何限制地显示文本

@Composable
fun PlanesScreen(viewModel : PlanesViewModel){
    PlaneList(viewModel.planeInfo().observeAsState())
}

我通过observeAsSateLiveData 转换为State,然后将其传递给显示文本的方法。

在这一次中,我在 UiResponse 上执行我的 when 以对响应的不同状态做出反应

@Composable
fun PlaneList(state: State<UiResponse<ArrayList<PlaneInfo>>?>){

    state.value.let {
        when(it){
            is UiResponse.Error ->  Text(text = "Error")
            is UiResponse.Loading -> Text(text = "Loading")
            is UiResponse.Success -> it.data.forEach { Text(text = it.registration) }
        }
    }

} 

当我编译应用程序时,屏幕包含文本Loading,然后是打印列表的结果,但是当我查看 Chuck 时,我有两次调用我的数据库。

在使用调试器时,我注意到启动 PlaneScreenNavHost 的可组合项被调用了两次,这导致了我的问题。

无论我看了多少,我都找不到解决方案,以便能够将 ViewModel 传递给 NavHost 中的可组合对象,并且即使在重新组合屏幕时也只进行一次调用

您知道如何解决这个问题而不必将viewModels 传递给我的Navigation 函数吗?

【问题讨论】:

    标签: android kotlin android-jetpack-compose android-viewmodel kotlin-flow


    【解决方案1】:

    我发现了我的问题。我正在查看我的 ViewModel 中的一个函数,而不是一个变量:

    fun planeInfo() : LiveData<UiResponse<ArrayList<PlaneInfo>>> {
        return planeInfoUseCase.execute().toUiResponse().flowAsLiveData(Dispatchers.IO)
    }
    

    我把它改成了:

    val planeInfo : LiveData<UiResponse<ArrayList<PlaneInfo>>> = planeInfoUseCase.execute().toUiResponse().flowAsLiveData(Dispatchers.IO)
    

    我一直想知道为什么要在 ViewModel 中遍历变量,我现在有了答案。

    【讨论】:

      猜你喜欢
      • 2020-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-14
      • 2018-01-12
      • 2016-06-22
      相关资源
      最近更新 更多