'Recycle view Overlaying in androidx.constraintlayout.helper.widget.Flow

Facing an issue recycle view is overlapping in Widget.Flow layout. First-time app installation is working fine as excepted but user scrolls up and done items are overlapping every time, not able to fix the issue anyone have idea help on the same.

ConstraintLayout: This layout will decide the percentage of the width.

FLOW: Flow layout will display dynamic text view to next row automatically if textview with is fit.

Attaching the sample code for reference.

Activity

class MainActivity : AppCompatActivity() {
 private lateinit var customAdapter: CustomAdapter

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val list = intArrayOf(1, 2)
    val listSize = intArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 4, 4, 4, 4, 4, 44, 4, 4, 4, 4, 4, 4, 5)

    val order_details_list = findViewById<RecyclerView>(R.id.order_details_list)

    //CustomAdapter(this, list)
    customAdapter = CustomAdapter(this@MainActivity, list, listSize)
    val recyclerViewLayoutManager =
        LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
    order_details_list.layoutManager = recyclerViewLayoutManager
    order_details_list.adapter = customAdapter

 }
} 

Adapter

       class CustomAdapter(
    private val context: Context?,
    private val list: IntArray,
    private val listSize: IntArray
       ) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val inflater =
            parent.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        val view = inflater.inflate(R.layout.row_order_layout_new, parent, false)
        return DetailViewHolder(view)
    }

    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
        val holder = viewHolder as DetailViewHolder
        setData(holder, listSize)
    }

    private fun setData(holder: DetailViewHolder, intArray: IntArray) {
        System.out.println(" array ====> " + "setData")
        val intArrays = IntArray(intArray.size)
        var count = 1;
        for (i in intArray.indices) {
            println(i)

            val orderNo = TextView(context)
            orderNo.text = "orderNo " + i
            orderNo.id = count
            orderNo.isSingleLine = true
            orderNo.ellipsize = (TextUtils.TruncateAt.END)
            val lp = ConstraintLayout.LayoutParams(0, ConstraintLayout.LayoutParams.WRAP_CONTENT)
            lp.matchConstraintPercentWidth = 0.5.toFloat()
            orderNo.layoutParams = lp

            intArrays[i] = count
            count++

            holder.constraintLayout.addView(orderNo)

        }

        System.out.println(" array ====> " + list.size)
        holder.flowLayout.referencedIds = (intArrays)
    }

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

    //Custom ViewHolder
    open class ViewHolder(v: View?) : RecyclerView.ViewHolder(v!!)

    inner class DetailViewHolder(itemView: View) : ViewHolder(itemView) {
        var constraintLayout: ConstraintLayout = itemView.findViewById(R.id.main_Layout)
        var flowLayout: androidx.constraintlayout.helper.widget.Flow = itemView.findViewById(R.id.flowLayout);
    }
}

XML

<?xml version="1.0" encoding="utf-8"?>
  <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_Layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<androidx.constraintlayout.helper.widget.Flow
    android:id="@+id/flowLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#e4e4e4"
    app:flow_horizontalAlign="start"
    app:flow_horizontalBias="0"
    app:flow_horizontalStyle="packed"
    app:flow_maxElementsWrap="10"
    app:flow_verticalAlign="top"
    app:flow_verticalBias="0"
    app:flow_verticalGap="0dp"
    app:flow_wrapMode="chain"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<View
    android:layout_width="match_parent"
    android:layout_height="2dp"
    android:background="@color/black" />

  </androidx.constraintlayout.widget.ConstraintLayout>

Attaching screen shots for reference.

enter image description here enter image description here



Solution 1:[1]

Solution: Keep ids references and re-use them later. RecyclerView didn't know how to handle your case because of reusability and programatically created views.

Additional: If you create view's programmatically you can use View.generateViewId() to generate viewId.

Code:

inner class DetailViewHolder(itemView: View) : ViewHolder(itemView) {
        private val constraintLayout: ConstraintLayout = itemView.findViewById(R.id.main_Layout)
        private val flowLayout: androidx.constraintlayout.helper.widget.Flow =
            itemView.findViewById(R.id.flowLayout)

        private val ids = mutableListOf<Int>()

        fun setData(intArray: IntArray) {

            if (ids.size  == 0) {
                for (i in intArray.indices) {
                    println(i)

                    val orderNo = TextView(context)
                    orderNo.text = "orderNo " + i
                    orderNo.setTextColor(Color.BLACK)
                    orderNo.id = View.generateViewId()
                    orderNo.isSingleLine = true
                    orderNo.ellipsize = (TextUtils.TruncateAt.END)
                    val lp =
                        ConstraintLayout.LayoutParams(0, ConstraintLayout.LayoutParams.WRAP_CONTENT)
                    lp.matchConstraintPercentWidth = 0.5.toFloat()
                    orderNo.layoutParams = lp

                    ids.add(orderNo.id)
                    constraintLayout.addView(orderNo)

                }
            }

            flowLayout.referencedIds = ids.toIntArray()
        }
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1