У меня есть БД, заполненная данными о погоде, как в имперских, так и в метрических единицах. Теперь я сделал два разных класса, которые действуют как модель для получения данных из БД. CurrentWeatherMetric
имеет только метрические столбцы, а CurrentWeatherImperial
имеет только имперские поля.
Поскольку я использую шаблон архитектуры MVVM, ViewModel
предоставляет мне эти данные, вызывая функцию в ViewModel getData(Unit.METRIC)
, где Unit
— это enum class
, который я сделал для различения данных.
Проблема возникает здесь. Моя модель просмотра выглядит так:
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>
,
Мне пришлось сделать еще один класс, в котором хранятся данные запроса с единицами измерения. Я сделал это так, чтобы легко реализовать с его помощью привязку данных. Но я чувствую, что это действительно неправильный способ делать что-то, и поэтому я задал этот вопрос. Как я могу избавиться от этой переменной lateinit
и реализовать привязку данных, чтобы адаптироваться к любым данным.
В моем текущем макете привязки данных у меня есть поле данных как:
<data>
<variable
name = "viewModel"
type = "com.mythio.weather.ui.WeatherViewModel" />
</data>
И я привязываюсь к представлениям:
app:someattribute = "@{viewModel.currentWeather.temperature}"
Если заголовок вопроса имеет небольшое представление о том, о чем я спрашиваю, или кажется вводящим в заблуждение, пожалуйста, отредактируйте его, чтобы сделать его лучше.
Итак, то, как я реализовал остальную часть кода, в порядке?
Да, следовать MVVM и получать данные из репозитория, на мой взгляд, лучше всего. Рекомендуемый способ - привязать ViewModel к пользовательскому интерфейсу и получить данные из репозитория, который всегда будет единственным источником правды для ваших данных.
Хорошо спасибо! Если вы напишете ответ, я отмечу его как правильный
Но я не очень помог тебе получить такую репутацию.
Это все еще очень помогло мне, как новичку в kotlin и mvvm.
При использовании Шаблон архитектуры MVVM способ рекомендовано Google состоит в том, чтобы сделать ViewModel
, который обрабатывает связь между вашим данные и просмотр, поэтому он содержит логику пользовательского интерфейса, а также некоторую часть бизнес-логики, связанную с вашим пользовательским интерфейсом.
Более того, реализация ViewModel
рекомендуемым способом поможет вам лучше и без проблем обрабатывать Жизненный цикл пользовательского интерфейса (активность/фрагменты).
При использовании привязка данных с MVVM рекомендуется привязывать ViewModel
напрямую к xml, чтобы при изменении данных вы могли напрямую отражать их в пользовательском интерфейсе с помощью LiveData
, не подключая их вручную.
Следовательно, LiveData
можно использовать в качестве держателя значения данных, так как это также Компонент с учетом жизненного цикла.
С другой стороны, Репозитории — это хороший способ управлять бизнес-логика и предоставлять "единственный источник правды" для передачи данных через приложение. Таким образом, все источники данных, такие как локальная БД, вызовы API, общие настройки и т. д., должны быть доступны через репозиторий.
Так да!! Все, что вы делаете, хорошо, и вы на правильном пути, следуя Шаблон архитектуры MVVM.
Note: You can refer here for more info and some improvements in your code.
Несмотря на использование поздно, вы также можете инициализировать его с помощью
MutableLiveData
в той же строке с объявлением, например,val data: LiveData<> = MutableLiveData()
. Хотя привязка пользовательского интерфейса мне кажется нормальной.