在 androidx.constraintlayout.helper.widget.Flow 中回收视图叠加

问题描述

面对问题回收视图在 Widget.Flow 布局中重叠。 首次安装应用程序正常工作,但用户每次向上滚动和完成的项目都重叠,无法解决任何有想法帮助的问题。

ConstraintLayout:此布局将决定宽度的百分比。

FLOW:如果 textview 适合,Flow 布局会自动动态文本视图显示到下一行。

附上示例代码以供参考。

活动

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,44,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

 }
} 

适配器

       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>

附上屏幕截图以供参考。

enter image description here

enter image description here

解决方法

解决方案:保留 ID 引用并在以后重新使用它们。由于可重用性和以编程方式创建的视图,RecyclerView 不知道如何处理您的案例。

附加: 如果您以编程方式创建视图,则可以使用 View.generateViewId() 生成 viewId

代码

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