【问题标题】:How to change the background color of selected item in RecyclerView如何在 RecyclerView 中更改所选项目的背景颜色
【发布时间】:2019-07-02 09:49:44
【问题描述】:

我创建了一个 Kotlin 移动应用。在我的应用程序中,我使用带有适配器的RecyclerView。 我想更改在我的RecyclerView 中单击的项目的背景颜色,当我单击另一个项目时,颜色将发生变化,并且单击的第一个项目的颜色返回默认颜色。

override fun onBindViewHolder(holder: ViewHolder, position: Int) { 
       val itemCategory: ProductCategoryData = categories[position] 
       holder.categoryId.text = itemCategory.id.toString() 

       println(holder.categoryId.text) 
       println(itemCategory.name?.get("En").toString()) 
       holder.categoryName.text = itemCategory.name?.get("En").toString() 
      ............ 
       holder.itemView.setOnClickListener { 
           rowindex = position 
           mListener?.onItemClick(holder.itemView, categories[position]) 
       } 
       if (rowindex == position) { 
           holder.itemView.setBackgroundColor(Color.parseColor("#FED07A")) 
       } else { 
           holder.itemView.setBackgroundColor(Color.parseColor("#ffffff")) 
       } 

   }

我应该在我的代码中进行哪些更改以使其正常运行

【问题讨论】:

  • 只是缺少notifyDataSetChanged,以便通知适配器它需要重新运行onBindViewHolder
  • 您可以保存最后点击的项目和新点击的项目的索引,然后使用适配器的 notifyItemChanged(itemIndex) 更改项目的背景

标签: android kotlin android-recyclerview


【解决方案1】:

调用 notifyDataSetChanged

holder.itemView.setOnClickListener { 
   rowindex = position 
   mListener?.onItemClick(holder.itemView, categories[position])
   notifyDataSetChanged()          
} 

if (rowindex == position) {            
    holder.itemView.setBackgroundColor(Color.parseColor("#FED07A")) 
} else { 
    holder.itemView.setBackgroundColor(Color.parseColor("#ffffff")) 
}  

【讨论】:

    【解决方案2】:

    要更改 RecyclerView 中点击项目的背景,您需要使用 iterface 捕捉适配器中的点击:

    interface ItemClickListener {
        fun onItemClickListener(item: Item, position: Int)
    }
    

    当我们单击时,我们将获得项目和项目位置。在适配器的绑定函数中,我们将设置点击监听器:

    container.setOnClickListener {
        onClickListener.onItemClickListener(item, position)
    }
    

    在您的活动中,您将实现此接口:

    class MainActivity : AppCompatActivity(), ItemAdapter.ItemClickListener {
    

    接下来我们需要实现项目点击的背景变化逻辑。逻辑是这样的:当用户点击一个项目时,我们检查被点击项目的背景是否为白色(该项目之前没有被点击过),如果这个条件为真,我们改变所有项目的背景RecyclerView 为白色(如果有的话,使之前单击和标记的项目无效),然后将单击项目的背景颜色更改为蓝绿色以标记它。如果点击项目的背景是蓝绿色(这意味着用户再次点击之前标记的相同项目),我们将所有项目的背景颜色更改为白色。首先,我们需要将项目背景颜色作为 ColorDrawable。我们将使用迭代器函数遍历 RecyclerView 的所有项目(子项),并使用 forEach() 函数来更改每个项目的背景。这个方法看起来像这样:

     override fun onItemClickListener(item: Item, position: Int) {
            val itemBackground: ColorDrawable =
                binding.recycler[position].background as ColorDrawable
            if (itemBackground.color == ContextCompat.getColor(this, R.color.white)) {
                binding.recycler.children.iterator().forEach { item ->
                    item.setBackgroundColor(
                        ContextCompat.getColor(
                            this,
                            R.color.white
                        )
                    )
                }
                binding.recycler[position].setBackgroundColor(
                    ContextCompat.getColor(this, R.color.teal_200)
                )
            } else {
                binding.recycler.children.iterator().forEach { item ->
                    item.setBackgroundColor(
                        ContextCompat.getColor(
                            this,
                            R.color.white
                        )
                    )
                }
            }
        }
    

    所以现在你改变了点击项目的背景,如果你点击同一个项目,你会把背景改回原来的样子。

    【讨论】:

      【解决方案3】:

      此类问题的大部分答案,都是即将在 onBindViewHolder 中重写 Onclick 或在回收站视图中实现点击接口。但众所周知,在滚动期间填充您的视图时调用 onBindViewHolder。因此,您将多次调用 setOnClickListener,因此这不是一种有效的方法,而且实现接口也没有我得到的答案那么容易。

      您可以通过以下方式在回收站视图中访问选择项目并更改其背景或在选择项目时执行您想要的任何操作。

      在您的 ViewHolder 构造函数中,以这种方式为 itemView(构造函数的参数)使用 setOnTouchListener。

          itemView.setOnTouchListener((v, event) -> {
      
                      if (event.getAction() == MotionEvent.ACTION_UP) {
      
                          if (v.getTag() == null) {
                              v.setTag(true);
                              v.setBackgroundColor(Color.parseColor("#F31807"));
                          } else {
                              v.setBackgroundColor(Color.TRANSPARENT);
                              v.setTag(null);
                          }
                      }
      
                      if (event.getAction() == MotionEvent.ACTION_MOVE) {
                         //default color
                          v.setBackgroundColor(Color.TRANSPARENT);
                      }
                      return true;
                  });
      

      我们使用 ACTION_UP 来检查用户是否按下了该项目,然后我们在视图的标志中保存一个布尔值,以便我们可以按我们想要的次数按每个项目并看到颜色正在变化。 ACTION_MOVE 如果块用于防止在滚动回收器视图时选择项目。如果您发现选择一个项目正在影响另一个项目的选择,您可以使用以下答案:

      issue : RecyclerView messed up data when scrolling

      最后,如果你对我们为什么在方法中返回 true 感到好奇,请看这个视频来理解。

      tutorial on OnTouchListener And Motionevent

      【讨论】:

        猜你喜欢
        • 2023-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-16
        相关资源
        最近更新 更多