RecycleView list items not appearing

718 views Asked by At

I've been trying to make RecyclerView work in my app where the list items are ImageViews, and the images get downloaded and put inside (asynchronously) in the onBindViewHolder method. I'm not facing any errors in my code, but for some reason

only the list items which will be visible (even partially) to the user when the activity loads, have images loaded into them.

Though I can't see the images, I observed that the height and width of these items have been allocated correctly. And since the images get downloaded first, and then the ImageView's dimensions are determined I figure that the problem has got something to do with RecyclerView itself? If someone can shed some light on this, it would be great. Thanks.

I would also like to add, that if the Activity is paused and then resumed (by clicking on the "square" navigation button and then resuming it), the images of all the list items load correctly.

Pic #1 as you can see the gray portion where an image is supposed to be Pic #2 somewhat more convincing :)

Here's my code:

onCreate method:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        recyclerView {
            id = ViewID.ID_LIST
        }

        val imgList = ArrayList<ImageView>()
        imgList.add(ImageView(ctx))
        imgList.add(ImageView(ctx))
        imgList.add(ImageView(ctx))
        imgList.add(ImageView(ctx))
        val lv = findViewById(ViewID.ID_LIST) as RecyclerView
        lv.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
        lv.adapter = ImageRecyclerAdapter(ctx, imgList)

}

The RecyclerView.Adapter class:

private class ImageRecyclerAdapter(val context: Context, val imageList: ArrayList<ImageView>) :
            RecyclerView.Adapter<RecyclerView.ViewHolder>() {

        override fun onViewRecycled(holder: RecyclerView.ViewHolder?) {
            super.onViewRecycled(holder)
            if (holder != null) {
                val v = holder.itemView as ImageView
                v.setImageBitmap(null)
            }
        }

        override fun onBindViewHolder(p: RecyclerView.ViewHolder, position: Int) {
            val v = p.itemView as ImageView
            Ion.with(v)
                    .load("https://pbs.twimg.com/profile_images/616076655547682816/6gMRtQyY.jpg")
                    .setCallback({ exception, t ->
                        if (t != null) {
                            val dm = Point()
                            context.windowManager.defaultDisplay.getRealSize(dm)
                            val w = t.maxWidth
                            val h = t.maxHeight

                            val params = t.layoutParams
                            if (params != null) {
                                params.width = dm.x
                                params.height = (dm.x * (h.toDouble() / w.toDouble())).toInt()
                                t.layoutParams = params
                                t.requestLayout()
                            }
                        }
                    })
        }

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

        override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
            val v = ImageView(context)
            return object : RecyclerView.ViewHolder(v) {}
        }
    }
1

There are 1 answers

0
いちにち On

It worked after I made the binding of data into a Synchronous request, and I moved the ImageView manipulation (changing LayoutParams) into the onViewAttachedToWindow overridden method of my adapter.

onViewAttachedToWindow:

override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder?) {
    super.onViewAttachedToWindow(holder)
    val t = holder?.itemView as ImageView
    val dm = Point()
    context.windowManager.defaultDisplay.getRealSize(dm)
    val w = t.maxWidth
    val h = t.maxHeight
    val params = t.layoutParams
    if (params != null) {
        params.width = dm.x
        params.height = (dm.x * (h.toDouble() / w.toDouble())).toInt()
        t.layoutParams = params
        t.requestLayout()
    }
}

onBindViewHolder:

override fun onBindViewHolder(p: RecyclerView.ViewHolder, position: Int) {
    val v = p.itemView as ImageView
    Ion.with(v)
            .load(imageList[position].toString())
            .tryGet()
}