0 Soalan: Kedudukan penyemak semula ditetapkan semula apabila Imej dimuatkan menggunakan Picasso

soalan dicipta di Wed, May 8, 2019 12:00 AM

Saya mempunyai Recycler Recyclers yang memaparkan poster filem, sangat mirip dengan Netflix atau aplikasi yang paling kiat.
Apabila saya menatal lajur pendaur dalaman, saya mengambil imej dari URL menggunakan Picasso.
Ia berfungsi dengan baik, tetapi apabila setiap imej dimuatkan ke dalam imejnya, pandangan kedudukan kitar semula diletakkan pada 0 dan ia kembali ke baris pertama imej.

Ini ialah pengitar semula luar dan dalaman saya:

luar:

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)
    }

}

batin:

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
    }

}

Dan saya mencipta rekod luar saya dalam fragmen saya seperti:

...

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

...

Saya telah cuba untuk menyelesaikan masalah ini selama seminggu sekarang, tetapi tidak lebih dekat untuk menyelesaikannya ketika saya mula. Saya telah mencuba semua perkara yang saya dapati di internet, tetapi tidak berjaya setakat ini. Perkara yang saya cuba lakukan termasuk:

  • Menetapkan setHasStableIds(true) dan mengesahkan getItemId(position: Int)
  • Override getItemViewType(position: Int) untuk kembali posisi
  • Lulus kolam paparan dikongsi ke pendaur semula dalaman setRecycledViewPool(viewPool)
  • Cuba banyak variasi pilihan Picasso (ruang letak, pemprosesan imej, panggilan balik, dan lain-lain) untuk cuba memerintah sesuatu.
  • Lulus Presenter memegang data dan bukan lulus data itu sendiri.

Saya juga harus menambah bahawa saya hanya membuat satu permulaan data, jadi notifikasiDataSetChanged hanya dipanggil masa pertama (dan hanya) serpihan itu disediakan.

Saya dengan senang hati memberikan maklumat lanjut jika diperlukan. Saya hanya mahu menutup bab ini dan teruskan dengan projek itu.

    
0
  1. Kemas kini: Saya menukar peranti ujian dari Google Nexus (Android 7.1.1, API 25) ke Samsung Galaxy s10 (Android 9, API 28) dan bugg hilang. Mana-mana meneka apa yang sedang bermain di sini?
sumber diletakkan di sini