Наблюдение LiveData в RecyclerView - PullRequest
0 голосов
/ 27 марта 2020

Короче говоря: у моего ViewModel есть свойство LiveData, которое должно влиять на данные, отображаемые моими (привязанными данными) RecyclerView элементами.

Сам набор данных (элементы списка) не изменяется, должна отображаться только информация, отображаемая элементами списка.

ViewModel.kt

val condition: LiveData<Boolean>

Item.kt

data class Item(
    val a: String = "A",
    val b: String = "B"
) {
    fun getText(condition: Boolean) = if (condition) a else b
}

item_row. xml

<variable
    name="item"
    type="my.package.Item"/>

<variable
    name="model"
    type="my.package.ViewModel"/>

<!--Some TextView-->
android:text="@{item.getText(model.condition)}"

Теперь самое интересное. чтобы мой ViewHolder мог наблюдать LiveData, он реализует интерфейс LifecycleOwner. Его состояние изменяется с помощью присоединенных / отсоединенных обратных вызовов RecyclerView.Adapter.

DataBoundViewHolder.kt

class DataBoundViewHolder(private val binding: ViewDataBinding) :
    RecyclerView.ViewHolder(binding.root), LifecycleOwner {

    private val lifecycleRegistry = LifecycleRegistry(this)

    init {
        lifecycleRegistry.currentState = Lifecycle.State.INITIALIZED
    }

    fun onViewAttachedToWindow() {
        lifecycleRegistry.currentState = Lifecycle.State.STARTED
    }

    fun onViewDetachedFromWindow() {
        lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
    }

    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistry
    }

    fun bind(item: Item, model: ViewModel) {
        binding.apply {
            setVariable(BR.item, item)
            setVariable(BR.model, model)
            executePendingBindings()
        }
    }
}

DataBoundAdapter.kt

abstract class DataBoundAdapter(private val model: ViewModel) :
    RecyclerView.Adapter<DataBoundViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DataBoundViewHolder {
        val binding = DataBindingUtil.inflate<ViewDataBinding>(
            LayoutInflater.from(parent.context),
            viewType,
            parent,
            false
        )
        return DataBoundViewHolder(binding).also { holder ->
            binding.lifecycleOwner = holder
        }
    }

    override fun onBindViewHolder(holder: DataBoundViewHolder, position: Int) {
        holder.bind(getItem(position), model)
    }

    override fun onViewAttachedToWindow(holder: DataBoundViewHolder) {
        super.onViewAttachedToWindow(holder)
        holder.onViewAttachedToWindow()
    }

    override fun onViewDetachedFromWindow(holder: DataBoundViewHolder) {
        super.onViewDetachedFromWindow(holder)
        holder.onViewDetachedFromWindow()
    }
}

Я полагал, что все это будет работать, и это вроде как ...

LiveData в ViewModel переключается с помощью кнопки пользовательского интерфейса. Пока список еще не прокручен, отображаемые в настоящий момент элементы перепривязываются, чтобы отразить новое состояние. Однако при прокрутке списка только часть просмотров обновляется при последующих нажатиях кнопки переключения.

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

Большое спасибо за вашу помощь.

...