每当使用Picasso加载图像时,回收站的位置都会重置

时间:2019-05-08 15:50:27

标签: android android-recyclerview picasso image-gallery nestedrecyclerview

我有一个回收站的回收站,可以显示电影海报,非常类似于Netflix或最讨厌的应用程序。
每当滚动内部回收站列时,我都会使用Picasso从URL中获取图像。
它的效果很好,但是只要将图像加载到其图像视图中,外部回收站的位置就会设置为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仅在第一次(且唯一)片段安装时被调用。

如果需要,我很乐意提供更多信息。 我只想关闭本章并继续进行该项目。

0 个答案:

没有答案