Привязка данных: передайте LiveData как есть в BindingAdapter и наблюдайте его с помощью LifecycleOwner - PullRequest
0 голосов
/ 21 ноября 2019

Я хочу передать LiveData как есть BindingAdapter.

Внутри BindingAdapter Я хочу сделать Transformations.map и отобразить различные параметры, которые пользователь может выбрать, и при нажатии отправитьверните результат, используя тот же LiveData.

Чтобы наблюдать LiveData в BindingAdapter, мне нужен доступ к LifecycleOwner, в идеале для фрагмента. Мне нужно это, если я хочу вызвать .observe для liveData или установить LifecycleOwner для новой привязки, которую я создаю внутри BindingAdapter.

Есть идеи, как мне это сделать?

1 Ответ

1 голос
/ 21 ноября 2019

Во-первых, я бы хотел порекомендовать вам не идти по дороге, вкладывая слишком много своей бизнес-логики в свои BindingAdapter с. Помимо хорошей практики использования связывателей для простой установки атрибутов стиля, я лично видел катастрофические спагетти-коды , вызванные слишком большой логикой в ​​адаптерах. Это очень схематичная практика, так как код запускается для каждого элемента, который слушает вашу привязку, каждый раз, когда ваши жизненные данные изменяются, так что ваша логика может стать довольно беспокойной, очень быстро, и производительность вашего приложения может также довольно быстро снизиться.

Сказав это, я не думаю, что вы должны передавать LiveData в свой переплет, а вместо этого Object E, который содержится в вашей жизни. Таким образом, вы можете:

  1. хранить свою работу внутри фрагмента, который имеет LifecycleOwner и является рекомендуемым способом наблюдения за изменениями, которые
  2. передают в ваш экземпляр LiveDataрезультат ваших Transformation и
  3. отображает его в вашем пользовательском интерфейсе, получая его напрямую через привязку

Таким образом, ваш адаптер имеет только логику для отображения результата / результатов и всехработа корректно обрабатывается фрагментом.


Реализация ViewModel

Если вы хотите продвинуться дальше, следуя рекомендованным Google компонентам архитектурыЯ бы посоветовал вам разместить логику внутри вашей ViewModel (если вы следуете шаблону MVVM) и вообще избегать использования фрагмента. Вы поместите переменную LiveData в вашу viewModel (скажем, var itemColor: LiveData<Int> = MutableLiveData<Int>(R.color.colorPrimary)), подключите ее к вашей привязке через xml, т.е.

app:showColor="@{viewModel.itemColor}"

и поместите всю логику ваших преобразований в функцию в viewModel,Установка значения itemColor будет напрямую отправлять значение вашему привязывающему адаптеру (showColor), и вы сможете использовать значение по мере необходимости, даже не касаясь фрагмента или не наблюдая за переменной!

Примечание : пожалуйста, не забудьте установить lifecycleOwner для вашей привязки внутри фрагмента следующим образом: binding.lifecycleOwner = this, иначе адаптер не будет прослушивать изменения.

Надеюсь, это помогло, Panos.

...