Положение Recycler сбрасывается всякий раз, когда изображение загружается с помощью Picasso - PullRequest
0 голосов
/ 08 мая 2019

У меня есть Recycler of Recyclers, который отображает постеры фильмов, очень похожие на Netflix или большинство галеристов приложений.
Всякий раз, когда я прокручиваю внутренние столбцы корзины, я извлекаю изображение из URL с помощью Picasso.
Это прекрасно работает, но всякий раз, когда изображение загружается в его представление изображения, позиция внешнего рециклера устанавливается в 0 и возвращается к первому ряду изображений.

Это мой внешний и внутренний переработчик:

внешний:

class OuterPreviewRowAdapter(private var homeFeedResponse: MutableList<RelatedItemsResponse> = mutableListOf(),
                             private val onItemClick: ((Int) -> Unit)?)
    : RecyclerView.Adapter<OuterPreviewRowAdapter.ItemPreviewRowHolder>() {

    inner class ItemPreviewRowHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val recyclerView: RecyclerView = itemView.innerPreviewRecycler
        val categoryTitleTextView: TextView = itemView.innerListHeader
    }

    override fun onCreateViewHolder(parent: ViewGroup, p1: Int): ItemPreviewRowHolder {
        val itemRow = LayoutInflater.from(parent.context)
                .inflate(R.layout.component_item_preview_row, parent, false)
        return ItemPreviewRowHolder(itemRow)
    }

    override fun onBindViewHolder(holder: ItemPreviewRowHolder, position: Int) {
        val categoryModel = homeFeedResponse[position]
        val mediaItems = categoryModel.itemMediaPreviews?.filterNotNull() ?: listOf()

        holder.categoryTitleTextView.text = categoryModel.categoryName

        holder.recyclerView.apply {
            val innerLayoutManager = LinearLayoutManager(holder.itemView.context, LinearLayoutManager.HORIZONTAL, false)
            layoutManager = innerLayoutManager
            adapter = InnerPreviewItemAdapter(mediaItems, onItemClick)
        }
    }

    override fun getItemCount(): Int {
        return homeFeedResponse.size
    }

    fun updateDataSetAndNotify(newFeed: List<RelatedItemsResponse>) {
        homeFeedResponse.addAll(newFeed)
    }

}

внутренний:

class InnerPreviewItemAdapter(private var mediaPreviewItems: List<ItemMediaPreviewsItem>,
                              private val onItemClick: ((ItemId: Int) -> Unit)?)
    : RecyclerView.Adapter<InnerPreviewItemAdapter.ItemPreviewHolder>() {

    inner class ItemPreviewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var itemTitle: TextView = itemView.itemTitle
        var itemDuration: TextView = itemView.itemDuration
        var itemPreviewImage: ImageView = itemView.itemPreviewImage
        var progressSpinnerItemPreview: View = itemView.progressSpinnerItemPreview
    }

    override fun onCreateViewHolder(parent: ViewGroup, p1: Int): ItemPreviewHolder {
        val previewItemView = LayoutInflater.from(parent.context)
                .inflate(R.layout.component_item_preview_item, parent, false)
        return ItemPreviewHolder(previewItemView)
    }

    override fun onBindViewHolder(holder: ItemPreviewHolder, position: Int) {
        val mediaItem = mediaPreviewItems[position]

        holder.apply {
            mediaItem.id?.let { itemId -> itemView.setOnClickListener { onItemClick?.invoke(itemId) } }
            progressSpinnerItemPreview.visibility = View.VISIBLE
            itemTitle.text = mediaItem.title
            itemDuration.text = itemDuration.context.getString(R.string.MINUTES_WITH_ARGUMENT, mediaItem.length)
        }

        // TODO: (broel) disabling picasso solves the gallery recycler bug.
        Picasso.get().load(mediaItem.contentPoster)
                .fit()
                .centerInside()
                .error(R.drawable.ic_missing_content)
                .into(holder.itemPreviewImage)
    }

    override fun getItemCount(): Int {
        return mediaPreviewItems.size
    }

}

И я создаю свой внешний переработчик в своем фрагменте так:

...

private fun setupMediaGalleryRecycler() {
        val linearLayoutManager = LinearLayoutManager(context)
        outerRecyclerAdapter = OuterPreviewRowAdapter(onItemClicked)
        outerPreviewRecycler.adapter = outerRecyclerAdapter
        outerPreviewRecycler.itemAnimator = DefaultItemAnimator()
        outerPreviewRecycler.layoutManager = linearLayoutManager
    }

...

Я пытался решить эту проблему уже неделю, но не приблизился к ее решению тогда, когда начал. Я перепробовал все, что могу найти в сети, но пока безуспешно. Вот что я пробовал:

  • Настройка setHasStableIds(true) и переопределение getItemId(position: Int)
  • Переопределить getItemViewType(position: Int) для возврата в положение
  • Передача общего пула просмотра внутреннему переработчику setRecycledViewPool(viewPool)
  • Попытка множества вариантов параметров Picasso (заполнителей, обработки изображений, обратных вызовов и т. Д.), Чтобы попытаться что-то исключить.
  • Передать Presenter, держа данные вместо того, чтобы передавать сами данные.

Я также должен добавить, что я делаю только одну начальную выборку данных, поэтому notifyDataSetChanged вызываются только в первый (и единственный) раз, когда фрагмент настроен.

Я рад предоставить больше информации, если это необходимо. Я просто хочу закрыть эту главу и продолжить работу над проектом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...