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

вопрос создан в Wed, May 8, 2019 12:00 AM

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

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

external:

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 вызываются только в первый (и единственный) раз, когда фрагмент настроен.

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

    
0
  1. Обновление: я изменил тестовое устройство с Google Nexus (Android 7.1.1, API 25) на Samsung Galaxy s10 (Android 9, API 28), и ошибка исчезла. Есть предположения, что здесь происходит?
    2019-05-09 09: 20: 52Z
0 ответов                              0                         
источник размещен Вот