Лучший способ обновить один элемент с помощью библиотеки подкачки

Как лучше всего обновить один элемент при использовании новой библиотеки подкачки?

Допустим, у нас есть образец Google Paging with network с использованием PageKeyedSubredditDataSource . Представьте, что мы хотим изменить один элемент RedditPost. Итак, мы хотим проверить, есть ли он в списке, и если да, то обновить его. Обновление не должно быть таким простым, как вызов invalidate(), который вызовет первую страницу (возможно, RedditPost находится на 5-й странице. Мы не хотим обновлять все элементы, только один).


person Damia Fuentes    schedule 31.05.2018    source источник
comment
см. developer.android.com/reference/android/arch/paging/DataSource, раздел Updating Paged Data, последний абзац   -  person pskink    schedule 31.05.2018
comment
Спасибо. Но есть ли способ без использования in-memory?   -  person Damia Fuentes    schedule 31.05.2018
comment
вы используете PagedListAdapter? если да, то как тебе DiffCallback?   -  person pskink    schedule 31.05.2018
comment
Да. val POST_COMPARATOR = объект: DiffUtil.ItemCallback‹UserEntity›() { переопределить fun areContentsTheSame(oldItem: UserEntity, newItem: UserEntity): Boolean = oldItem == newItem переопределить fun areItemsTheSame(oldItem: UserEntity, newItem: UserEntity): Boolean = oldItem. идентификатор == новыйItem.id }   -  person Damia Fuentes    schedule 31.05.2018
comment
@DamiaFuentes у тебя получилось? Я могу успешно обновить список, который перескакивает в начало каждый раз, когда элементы обновляются.   -  person Keivan Esbati    schedule 30.06.2018
comment
Я серьезно не понимаю, почему комната использует LiveData повсюду, но библиотека подкачки должна получать фиксированные данные, или нам нужно реализовать какой-то хакерский способ в памяти, чтобы сделать недействительными все источники данных. Любые решения здесь? Моя база данных постоянно меняется и поэтому выдает значения liveData‹TableEntry›, которые плохо работают с библиотекой подкачки.   -  person JacksOnF1re    schedule 26.09.2018
comment
@KeivanEsbati Проверьте ответ!   -  person Damia Fuentes    schedule 27.09.2018
comment
@DamiaFuentes Я буду! Спасибо   -  person Keivan Esbati    schedule 27.09.2018


Ответы (1)


Обратите внимание, что все это работает через пейджинг с сетью Google. образец. Хотя что, идея есть.

@Sarquella помогла мне с этим решением. Добавьте эти классы в свой проект. По сути, мы расширяем ViewHolder до LifeCycle Owner, как это уже сделано по умолчанию с Activities и Fragments.

LifecycleViewHolder:

abstract class LifecycleViewHolder(itemView: View) :
        RecyclerView.ViewHolder(itemView),
        LifecycleOwner {

    private val lifecycleRegistry = LifecycleRegistry(this)

    fun onAttached() {
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
    }

    fun onDetached() {
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
    }

    override fun getLifecycle(): Lifecycle = lifecycleRegistry
}

LifecycleOwner — это интерфейс с одним методом, который обозначает, что у класса есть Lifecycle. Дополнительную информацию можно найти здесь.

LifecyclePagedListAdapter:

abstract class LifecyclePagedListAdapter<T, VH : LifecycleViewHolder>(diffCallback: DiffUtil.ItemCallback<T>) :
        PagedListAdapter<T, VH>(diffCallback) {

    override fun onViewAttachedToWindow(holder: VH) {
        super.onViewAttachedToWindow(holder)
        holder.onAttached()
    }

    override fun onViewDetachedFromWindow(holder: VH) {
        super.onViewDetachedFromWindow(holder)
        holder.onDetached()
    }
}

LifecycleAdapter (если вам это нужно):

abstract class LifecycleAdapter<VH : LifecycleViewHolder> :
        RecyclerView.Adapter<VH>() {

    override fun onViewAttachedToWindow(holder: VH) {
        super.onViewAttachedToWindow(holder)
        holder.onAttached()
    }

    override fun onViewDetachedFromWindow(holder: VH) {
        super.onViewDetachedFromWindow(holder)
        holder.onDetached()
    }
}

Затем расширяет MyAdapter до LifecyclePagedListAdapter<MyEntity, LifecycleViewHolder>(MY_COMPARATOR) и MyViewHolder до LifecycleViewHolder(view). Вы должны будете завершить свои занятия на основе того, что мы изменили соответственно. Теперь мы можем наблюдать за объектом liveData в классе MyViewHolder. Таким образом, мы можем добавить это в класс MyViewHolder (при условии, что вы используете внедрение зависимостей). По сути, мы будем делать то же самое, что и для Fragments или Activities:

private lateinit var myViewModel: MyViewModel

init {
    (itemView.context as? AppCompatActivity)?.let{
        myViewModel = ViewModelProviders.of(it).get(MyViewModel::class.java)
    }
}

Затем внутри метода bind():

fun bind(myCell: MyEntity?) {
    myViewModel.myLiveData.observe(this, Observer {
        // Buala!! Check if it is the cell you want to change and update it.
        if (it != null && myCell != null && it.id == myCell.id) {
           updateCell(it)
        }
    })
}
person Damia Fuentes    schedule 27.09.2018
comment
Привет, Дамиа, могу я спросить, есть ли какой-нибудь пример кода, демонстрирующий все необходимые изменения? Я чувствую себя потерянным, когда просматриваю метод bind() и updateCell. - person Tony Thompson; 24.12.2018
comment
@Damia Fuentes Не могли бы вы предоставить какой-либо рабочий образец для обновления конкретной страницы. - person Badhrinath Canessane; 12.03.2019
comment
@TonyThompson Вы можете найти библиотеку, реализующую все эти изменения, а также пример приложения здесь: github.com/Sarquella/LifecycleCells - person Sarquella; 26.11.2019
comment
@BadhrinathCanessane Вы можете найти библиотеку, реализующую все эти изменения, а также пример приложения здесь: github.com/Sarquella/LifecycleCells - person Sarquella; 26.11.2019