在回收站视图中滚动时数据消失

Data disappears when scrolling in recycler view

美好的一天。所以我目前在我的回收站视图中有数据。它现在只是静态数据。我仍然需要在我导入的地方做代码。然而,我的问题是我有一个按钮可以更改文本视图的背景。这发生在我的适配器中。当我滚动浏览我的列表时,bg 颜色变化会恢复到单击按钮之前的状态。我已经阅读了很多类似的问题,但无法真正找到一个解释清楚或对我有用的问题。根据我的阅读,数据被重置为静态数据,因为它当前正在我的 onBindViewHolder 中发生,我认为这会更改每次读取(滚动)新数据时的数据。我读到我应该创建一个 link 或一个监听器,然后调用它。但这对我来说没有意义,因为如果 link 被调用的次数与代码执行的次数相同,那么它将是相同的,不是吗。也许有一个条件侦听器,但不确定这是否可行。

我对 android 和科特林有些陌生。现在已经使用它一个月了。我不知道我在做什么,但我得到了最后期限。很遗憾没有时间去学习基础知识。感谢您提供的所有帮助。如果您需要任何额外的 code/information

,请告诉我

我的适配器

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RowViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.table_list_item, parent, false)
        return RowViewHolder(itemView)


    }

    private fun setHeaderBg(view: View) {
        view.setBackgroundResource(R.drawable.table_header_cell_bg)
    }

    private fun setContentBg(view: View) {
        view.setBackgroundResource(R.drawable.table_content_cell_bg)
    }

    override fun onBindViewHolder(holder: RowViewHolder, position: Int) {

      //  (TableViewAdapter.DataviewHolder) .bind()

        val rowPos = holder.adapterPosition



        if (rowPos == 0) {
            // Header Cells. Main Headings appear here
            holder.itemView.apply {
                setHeaderBg(txtWOrder)
                setHeaderBg(txtDElNote)
                setHeaderBg(txtCompany)
              //  setHeaderBg(txtAddress)
                setHeaderBg(txtWeight)
                setHeaderBg(txtbutton1)
                setHeaderBg(txtbutton2)
                setHeaderBg(txttvdone)


                txtWOrder.text = "WOrder"
                txtDElNote.text = "DElNote"
                txtCompany.text = "Company"
               // txtAddress.text = "Address"
                txtWeight.text = "Weight"
                txtbutton1.text = "Delivered"
                txtbutton2.text = "Exception"
                txttvdone.text = ""
            }
        } else {
            val modal = Tripsheetlist[rowPos - 1]

            holder.itemView.apply {
                setContentBg(txtWOrder)
                setContentBg(txtDElNote)
                setContentBg(txtCompany)
              //  setContentBg(txtAddress)
                setContentBg(txtWeight)
                setContentBg(txtbutton1)
                setContentBg(txtbutton2)
                setContentBg(txttvdone)

                txtWOrder.text = modal.WOrder.toString()
                txtDElNote.text = modal.DElNote.toString()
                txtCompany.text = modal.Company.toString()
              //  txtAddress.text = modal.Address.toString()
                txtWeight.text = modal.Weight.toString()
                txtbutton1.text = modal.Button1.toString()
                txtbutton2.text = modal.Button2.toString()
                txttvdone.text = modal.tvdone.toString()
            }
        }

        holder.apply {
            txtbutton1.setOnClickListener {
                Log.e("Clicked", "Successful delivery")
                txttvdone.setBackgroundResource(R.color.green)
                txttvdone.setText("✓")
            }
            txtbutton2.setOnClickListener {
                Log.e("Clicked", "Exception on delivery")
                txttvdone.setBackgroundResource(R.color.orange)
                txttvdone.setText("x")
            }



        }



    }

    class RowViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
         
     val txttvdone:TextView = itemView.findViewById<TextView>(R.id.txttvdone)
         val txtbutton1:Button = itemView.findViewById<Button>(R.id.txtbutton1)
         val txtbutton2:Button = itemView.findViewById<Button>(R.id.txtbutton2)
     }      class MyViewHolder(val view: View) : RecyclerView.ViewHolder(view){


        var txtbutton1 = view.findViewById<Button>(R.id.txtbutton1)
        val txtbutton2:Button = itemView.findViewById<Button>(R.id.txtbutton2)
        var txttvdone = view.findViewById<TextView>(R.id.txttvdone)
    }

我试过 (TableViewAdapter.DataviewHolder) .bind() 这样做并创建另一个 class 正如我看到的那样是在另一个线程中完成的 () 这很像我的问题.我似乎无法实施他的解决方案来使我的工作正常进行。 (没有完全理解他的解决方案)

//我也知道我正在使用将在年底到期的 android 扩展。但现在它可以工作,一旦我准备好代码并且 运行 我将开始转向更新版本的 kotlin。

顾名思义,RecyclerView 将在视图离开屏幕时回收视图。这意味着当一个项目的视图进入视图时,它会被重新创建并调用 onBindViewHolder() 来填充详细信息。

您的适配器内的 onClickListener 更改了单元格视图的其中一个子视图的背景。但是,如果该单元格离开屏幕并返回,它将被重新绘制。

为了解决这个问题,您的 onClickListener 应该更改数据项上的 属性,并且您的 onBindViewHolder 应该检查 属性 以确定要显示的背景颜色子视图:

enum class DataState {
    Unselected,
    Success,
    Failure
}
data class DataItem(var state: DataState = DataState.Unselected)

class MyAdapter : RecyclerView.Adapter<MyViewHolder>() {
    var dataItems: List<DataItem> = emptyList()

    fun updateData(data: List<DataItem>) {
        dataItems = data
        notifyDataSetChanged()
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val dataItem = dataItems[position]
        holder.txttvdone.apply {
            setBackgroundResource(when (dataItem.state) {
                DataState.Unselected -> android.R.color.transparent
                DataState.Success -> R.color.green
                DataState.Failure -> R.color.orange
            })
            text = when (dataItem.state) {
                DataState.Unselected -> ""
                DataState.Success -> "✓"
                DataState.Failure -> "x"
            }
        }

        holder.apply {
            txtbutton1.setOnClickListener {
                Log.e("Clicked", "Successful delivery")
                dataItem.state = DataState.Success
                notifyDataSetChanged()
            }
            txtbutton2.setOnClickListener {
                Log.e("Clicked", "Exception on delivery")
                dataItem.state = DataState.Failure
                notifyDataSetChanged()
            }
        }
    }
}