根据用户的查询获取数据并将其传递给数据绑定[使用MVVM]

Get data based on the user's query and pass it to databinding [uses MVVM]

我有一个数据库,其中填充了英制和公制单位的天气数据。现在,我制作了两个不同的 classes 作为从数据库获取数据的模型。 CurrentWeatherMetric 只有公制列,CurrentWeatherImperial 只有英制字段。

由于我使用的是 MVVM 架构模式,ViewModel 通过调用 ViewModel getData(Unit.METRIC) 中的一个函数为我提供了这些数据,其中 Unit 是一个 enum class 我'做了数据区分。

问题就出在这里。 我的 viewModel 看起来像:

class WeatherViewModel(
    private val weatherRepository: WeatherRepositoryImpl
) : ViewModel() {

    lateinit var currentWeather: LiveData<CurrentWeather>
    lateinit var forecastWeather: LiveData<List<ForecastWeather>>

    fun getValuesOfUnit(unit: Unit) {
        currentWeather = when (unit) {
            Unit.IMPERIAL->weatherRepository.getCurrentWeatherImperial()
            Unit.METRIC->weatherRepository.getCurrentWeatherMetric()
        }
        getWeather()
    }

    private fun getWeather() {

        viewModelScope.launch {
            try {
                weatherRepository.getWeather()
            } catch (e: IOException) {

            }
        }
    }
}

如您所见,lateinit var currentWeather: LiveData<CurrentWeather>, 我不得不制作另一个 class 来存储带有单位的查询数据。我这样做是为了可以轻松地用它实现数据绑定。但我觉得这是一种非常错误的做事方式,因此我提出了这个问题。我怎样才能摆脱那个 lateinit 变量并实现数据绑定以适应任何数据。

在我当前的数据绑定布局中,我的数据字段为:

<data>
    <variable
        name="viewModel"
        type="com.mythio.weather.ui.WeatherViewModel" />
</data>

我通过以下方式绑定到视图:

   app:someattribute="@{viewModel.currentWeather.temperature}"

如果问题标题对我的问题有一点意义,或者看起来具有误导性,请随时编辑它以使其成为一个更好的问题。

当使用MVVM架构模式时,Google的推荐方式是ViewModel 处理您的 数据和视图 之间的连接,因此它包含 UI 逻辑以及绑定到您的 [=65] 的部分业务逻辑=].

此外,以推荐的方式实施 ViewModel 可以帮助您更好地处理 UI 生命周期 (Activity/Fragments) 并且 hassle-free 方式。

data-binding 与 MVVM 一起使用时,最好将 ViewModel 直接绑定到 xml,这样,当数据更改时,您可以使用 LiveData 直接将其反映到 UI,无需手动接线。

因此,LiveData 可以用作 Data-Value 持有者,因为它也是 Lifecycle-aware 组件 .


另一方面,存储库 是管理业务逻辑 和提供"single source of truth" 的好方法 用于通过应用驱动的数据。因此,所有数据源,如 local-db、API 调用、shared-preferences 等都应通过存储库访问。

所以,是的!!您正在做的事情很好,并且您在遵循 MVVM 架构模式.

的同时走在了正确的轨道上

Note: You can refer here for more info and some improvements in your code.