首页 > 解决方案 > RecyclerView - 当我只想更新 1 个视图时更新 2 个视图

问题描述

我创建了一个 RecyclerView,用户可以在其中按下“现在”按钮,它会使用当前日期和时间更新回收站视图的 TextViews。

奇怪的是,如果我在位置 0 处按下回收站视图上的“现在”按钮,它也会在位置 9 处更新 RecyclerView。同样,在位置 1 处按下它也会在位置 10 处更新它。

目前,日期和时间没有保存在任何地方;那部分还没有设置。我只是想弄清楚为什么单击按钮会更新相隔 10 个位置的两个视图。

这是我的适配器的代码;我正在使用 Kotlin:

class TimeStampListAdapter(private val labelList: ArrayList<TimeStampLabels>,
                       private val context: Context) : RecyclerView.Adapter<TimeStampListAdapter.ViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, position: Int): ViewHolder {
    val view: View = LayoutInflater.from(context).inflate(R.layout.list_time_category, parent, false)
    return ViewHolder(view, context, labelList)
}

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

override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
    viewHolder?.bindItem(labelList[position])

}

 inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {

    var tsDate = itemView.findViewById(R.id.txtEDate) as EditText
    var tsTime = itemView.findViewById(R.id.txtETime) as EditText

    var categoryLabel = itemView.findViewById(R.id.txtVCategory) as TextView

    var nowButton = itemView.findViewById(R.id.btnNow) as Button

    val calendar = Calendar.getInstance()

    // Inserts the time stamp labels into each RecyclerView instance
    fun bindItem(label: TimeStampLabels) {

        categoryLabel.text = label.tsLabel
        nowButton.setOnClickListener(this)

    }



     override fun onClick(v: View?) {
         var dateFormat = SimpleDateFormat("MM / dd / yyyy")
         var timeFormat = SimpleDateFormat("HH:mm")
         var date = dateFormat.format(calendar.timeInMillis)
         var time = timeFormat.format(calendar.getTime())

         // Get the position of relevant row
         var position: Int = adapterPosition
         Log.d("POSITION:  ", position.toString())
         var mList = labelList[position]
         if (v!!.id == nowButton.id) {
             Log.d("POSITION in conditional", position.toString())
             tsDate.setText(date)
             tsTime.setText(time)


             //notifyItemChanged(adapterPosition) - This isn't needed, 
             // but if uncommented doesn't help the main issue I'm    
             // having.
         }

     }

触发覆盖的 onClick 函数时会出现此问题。

活动:

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



    labelListItems = ArrayList()
    adapter = TimeStampListAdapter(labelListItems!!, this )
    layoutManager = LinearLayoutManager(this)


    timeStampRecyclerView.layoutManager = layoutManager
    timeStampRecyclerView.adapter = adapter

    /**
     * Create the recycler views out of the TimeStampLabels table
     */
    for (i in 0..labels.timeStampLabels!!.size - 1) {
        val label = TimeStampLabels()
        label.tsLabel = label.timeStampLabels[i]
        labelListItems!!.add(label)
    }
    adapter!!.notifyDataSetChanged()
}

标签: androidandroid-recyclerviewkotlin

解决方案


发生这种情况是因为回收器视图顾名思义它回收(重用)视图,因此它可以节省内存并为用户提供流畅的滚动体验,请参阅此链接以获取更多详细信息https://developer.android.com/guide/topics/ui/布局/回收视图

因此,您在模型类 TimeStampLabels 中创建了另外两个字段,它们将存储日期和时间,然后您必须更改 onClick 实现,如下所示

override fun onClick(v: View?) {
    var dateFormat = SimpleDateFormat("MM / dd / yyyy")
    var timeFormat = SimpleDateFormat("HH:mm")
    var date = dateFormat.format(calendar.timeInMillis)
    var time = timeFormat.format(calendar.getTime())

    // Get the position of relevant row
    var position: Int = adapterPosition
    Log.d("POSITION:  ", position.toString())
    var mList = labelList[position]
    // What ever name you give for date and time field in your model class
    mList.date = date
    mList.time = time
    labelList[position] = mList
    notifyDataSetChanged()
}

并更改您的 bindItem 方法,如下所示

fun bindItem(label: TimeStampLabels) {
    // What ever name you give for date and time field in your model class
    tsDate.setText(label.date)
    tsTime.setText(label.time)
    categoryLabel.text = label.tsLabel
    nowButton.setOnClickListener(this)

}

推荐阅读