Как обновить изображения в RecyclerView?
У меня есть RecyclerView изображений, которые пользователь может редактировать непосредственно в самом RecyclerView.
Часть редактирования в порядке и работает хорошо. Это делается на растровом изображении, которое накладывает изображения, а затем сохраняет любые изменения в файл изображения. Как только пользователь прокручивает окно реселлера, растровое изображение уничтожается и становится невидимым.
Проблема в том, что любые изменения, сделанные пользователем, не видны при прокрутке. Они прокручивают СТАРОЕ изображение, а не ИЗМЕНЕННОЕ изображение. Они должны выйти из утилизатора и вернуться в него, чтобы увидеть изменения.
Так как же заставить RecyclerView перезагрузить только что сохраненное изображение. Я использую Glide в своем адаптере, и, как вы можете видеть, кеширование основано на времени сохранения изображения.
class InfinityPageAdapter(val memo: Memo) : ListAdapter<Page, InfinityPageAdapter.ViewHolder>(PageDiffCallback()) {
class ViewHolder(pageView: View) : RecyclerView.ViewHolder(pageView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): InfinityPageAdapter.ViewHolder {
val pageView = LayoutInflater.from(parent.context).inflate(R.layout.infinity_page_list_item, parent, false)
return ViewHolder(pageView)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val page = getItem(position)
val imageUrl = getMemoPath(memo.uuid) + page.uuid + ".webp"
if (imageUrl.isNotEmpty()) {
Glide.with(holder.itemView.context)
.load(imageUrl)
.apply(RequestOptions()
.signature(ObjectKey(System.currentTimeMillis()))
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.override(memo.pageWidth,memo.pageHeight)
)
.transition(DrawableTransitionOptions.withCrossFade())
.into(holder.itemView.findViewById(R.id.memo_page_image))
}
}
Есть ли способ уведомить переработчика о том, что изображение изменилось, и вызвать перезагрузку изображения?
Я использую DiffUtil на адаптере. Насколько я понимаю, мне не нужно использовать notifyDataSetChanged(), когда вы используете DiffUtil. Но я не понимаю, как вы уведомляете об изменении изображения.
Я не знаю, является ли Diff Callback проблемой. Для чего это стоит, вот оно. Он не смотрит на сам файл изображения, а только на имя файла изображения. Возможно, потому что имя не меняется, изображение не обновляется. Но я не хочу менять имя файла при каждом редактировании.
class PageDiffCallback : DiffUtil.ItemCallback<Page>() {
override fun areItemsTheSame(oldItem: Page, newItem: Page): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Page, newItem: Page): Boolean {
return oldItem == newItem
}
}
Спасибо!
Джон
1 ответ
Дело в том, что вы не обновляете весь элемент в своем представлении переработчика, это строка. NotifyDataSetChanged() принудительно обновит данные, как вы сказали, но в этом случае также обновит ваш макет.
С DiffUtil, помимо содержимого, вы также сравниваете, совпадают ли элементы, какими они являются, поскольку вы сравниваете их ID, и это не меняется при обновлении изображения.
Прежде чем пытаться с notifyDataSetChanged(), вы могли бы попытаться сделать это в вашем areContentsTheSame()
метод:
override fun areContentsTheSame(oldItem: Page, newItem: Page): Boolean {
return oldItem.id == newItem.id && oldItem.image == newItem.image // If you want just add more validations here
}