Я бы буквально имел 1 адаптер, который может рендерить все, используя класс DiffUtil
(или его асинхронную версию), чтобы гарантировать, что я не (и я цитирую) " перерисовываю все только потому, что одно свойство одного ChildModelизменения ».
Я бы перенес эту сложную обязанность по построению (и предоставлению) данных в ваш репозиторий (или, если вы предпочитаете, чтобы он был ближе, к вашей ViewModel, выступающей в качестве координатора между 1 или более (я неЯ не знаю, как выглядит ваша модель, поэтому я только воображаю) репозитории, предоставляющие данные.
Это позволит вам предложить ui гораздо более курируемый неизменный список ParentsAndChildren
вместе иответственность вашего RecyclerView / Adapter неожиданно становится намного проще, отобразите это и привяжите правильное представление для каждой строки. Ваш пользовательский интерфейс неожиданно быстрее, тратит гораздо меньше времени на выполнение задач в главном потоке, и вы даже можете тестировать логику для создания этого списка, полностью независимый от вашей Деятельности / Фрагмента.
Я предполагаю, что ParentsAndChildren будет выглядеть примерно так:
class ParentChildren(parent: Parent?, children: Children?)
Ваша привязка может затем раздувать одно представление, когда родитель не нулевойи дети есть. Когда дети не нуль, вы знаете, что это дети (вы могли бы также включить родителял, зависит от того, как вы строите эти данные).Проблема решена здесь, ваш адаптер будет выглядеть так:
class YourAdapter : ListAdapter<ParentChildren, RecyclerView.ViewHolder>(DiffUtilCallback()) {
...
Вам нужно будет реализовать DiffUtilCallback()
:
internal class DiffUtilCallback : DiffUtil.ItemCallback<ParentChildren>() {
и два его метода (areContentsTheSame
, areItemsTheSame
).
И два метода вашего адаптера:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return when (viewType) {
viewTypeParent -> YourParentViewHolder(inflater.inflate(R.layout.your_layout_for_parent), parent, false))
viewTypeChildren -> YourChildrenViewHolder(inflater.inflate(R.layout.your_layout_for_children), parent, false))
else -> throw IllegalArgumentException("You must supply a valid type for this adapter")
}
}
У меня была бы абстрактная база для еще большего упрощения адаптера:
internal abstract class BaseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
abstract fun bind(data: ParentChildren)
}
Это позволяет вам иметьваш
// I'm writing pseudo code here... keep it in mind
internal class ParentViewHolder(itemView: View) : BaseViewHolder(itemView) {
private val name: TextView = itemView.findViewById(R.id.item_text)
override fun bind(data: ParentChildren) {
name.text = parentChildren.parent?.name
}
}
internal class ChildrenViewHolder(itemView: View) : BaseViewHolder(itemView) {
private val name: TextView = itemView.findViewById(R.id.item_text)
override fun bind(data: ParentChildren) {
name.text = parentChildren.children?.name
}
}
Вы поняли.
Сейчас ... ListAdapter<>
имеет метод с именем submitList(T)
, где T - это тип адаптера ParentChildren
в приведенном выше псевдо-Пример.
Это все, что я знаю, и теперь вы должны предоставить эту активность или фрагмент, содержащий этот адаптер, список через LiveData или , независимо от того, что вы предпочитаете дляАрхитектура у вас есть.
Это может быть репозиторий, передающий его в MutableLiveData внутри viewModel и ViewModel, отображая LiveData<List<ParentChildren>
или похожий на пользовательский интерфейс.
Небо - это предел.
Это сдвигает сложность объединения этих данных, приближает их к месту, где мощь SQL / Room может использовать, как вы комбинируете и обрабатываете это, независимо от того, что пользовательский интерфейс хочет или хочет сделатьс этим.
Это мое предложение, но оно основано на очень ограниченных знаниях, которые у меня есть о вашем проекте.
Удачи!:)