переработчик просмотра мерцания привязки данных - PullRequest
0 голосов
/ 02 апреля 2019

Пользовательский интерфейс для этого действия имеет 4 кнопки, которые можно выбрать, и они должны отображаться синим цветом, если они выделены, и серым цветом, если они не выбраны.

the UI

первоначальный подход

конфигурация теперь представляет собой RecyclerView с одним типом элемента, который содержит все 4 кнопки:

<ConstraintLayout>
    <LinearLayout
      android:id="button1"
      background="@{viewModel.bgColor1}"... />

    <LinearLayout
      android:id="button2"
      background="@{viewModel.bgColor2}"... />

    <LinearLayout
      android:id="button3"
      background="@{viewModel.bgColor3}"... />

    <LinearLayout
      android:id="button4"
      background="@{viewModel.bgColor4}"... />

ПРИМЕЧАНИЕ: цвет текста также динамически привязывается к данным.

MyAdapter(
  config: AsyncDifferConfig<PartItemLifecycleModel>
): ListAdapter<MyModel, MyViewHolder<MyModel>>(config) {

  override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = 
    MyViewHolder(layoutInflator.inflate(R.layout.my_layout, parent, false))

  override fun onBindViewHolder(holder: MyViewHolder<MyModel>, position: Int) {
    holder.bindViewModel(items[i])
  }
}

class MyViewHolder(itemView: ViewGroup): RecyclerView.ViewHolder(itemView) {
  fun bindViewModel(viewModel: MyModel) {
    rootLayout?.let { layout ->
      binding = DataBindingUtil.bind<MyLayoutBinding>(layout)?.also {
        it.viewModel = viewModel
      }
    }
  }
}

всякий раз, когда я перепривязываю новую модель представления, вся иерархия представления перерисовывается и вызывает визуальное мерцание.

альтернативный подход

альтернативный подход, который я пробовал, состоит в том, чтобы каждый MyViewModel сравнивал одинаково (реализует equals / hashCode так, чтобы они всегда соответствовали друг другу) и заставлялRecyclerView для повторного использования сингла ViewModel.это работает несколько, однако пользовательский интерфейс (через привязку данных Android) не обновляется, пока кнопки не будут нажаты во второй раз.другими словами, когда выбрана кнопка-1, выбор кнопки-2 не обновляет представление, чтобы отразить его, пока кнопка-3 не будет нажата.при нажатии кнопки-3 пользовательский интерфейс обновляется, чтобы отразить нажатие кнопки-2, но не кнопки 3.

третий подход

третий подход, который не был реализован должным образом, заключается в реализации каждой кнопкикак отдельный тип RecyclerView и правильно реализуйте equals / hashCode.к сожалению, менеджер компоновки для RecyclerView, по-видимому, допускает только вертикальные элементы, каждый из которых занимает все горизонтальное пространство и переменное вертикальное пространство или наоборот.

...