点击按钮修改RecyclerView所有条目颜色时Adapter更新失效如何解决
问题原因
- 值传递导致两个
changecolor变量独立:布尔类型是值传递,初始化Adapter时把Activity的changecolor值传进去后,Adapter内部的changecolor和Activity的changecolor就失去关联,后续修改Activity的变量不会同步到Adapter内部。且Adapter里的changecolor用val修饰,本身就是不可修改的常量。
- 值传递导致两个
- 重复设置同一个Adapter不会触发刷新:点击按钮后给RecyclerView重新设置已经绑定过的同一个Adapter实例,RecyclerView不会重新渲染条目,自然不会执行
onBindViewHolder里的颜色判断逻辑。
- 重复设置同一个Adapter不会触发刷新:点击按钮后给RecyclerView重新设置已经绑定过的同一个Adapter实例,RecyclerView不会重新渲染条目,自然不会执行
解决方案
第一步:修改Adapter代码
调整内部changecolor为可修改的变量,新增更新状态并通知刷新的方法:
class Countryadapter( val countries: Array<String>, val itemClickListener: View.OnClickListener, initChangeColor: Boolean // 去掉val,仅作为初始值传入 ) : RecyclerView.Adapter<Countryadapter.ViewHolder>(){ // 改为可修改的var变量 var changecolor: Boolean = initChangeColor private set // 新增方法:更新颜色状态并通知列表刷新 fun updateColorState(needChange: Boolean) { changecolor = needChange // 全量刷新所有条目,也可使用notifyItemRangeChanged(0, itemCount)获得更好性能 notifyDataSetChanged() } class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val cardView = itemView.findViewById<CardView>(R.id.card_view) val icon = itemView.findViewById<ImageView>(R.id.icon) val name = itemView.findViewById<TextView>(R.id.name) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val inflater = LayoutInflater.from(parent.context) val viewItem =inflater.inflate(R.layout.item_country, parent, false) return ViewHolder(viewItem) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val country = countries[position] holder.icon.setImageResource(R.mipmap.ic_launcher_round) holder.name.text = country holder.cardView.tag = position holder.cardView.setOnClickListener(itemClickListener) if (changecolor){ holder.name.setTextColor(Color.parseColor("#f42069")) } else { // 补充默认颜色分支,避免RecyclerView条目复用导致颜色错乱 holder.name.setTextColor(Color.BLACK) } } override fun getItemCount(): Int = countries.size }
补充else分支是为了处理RecyclerView的条目复用机制,避免滑动列表时出现未修改状态的条目也显示为特殊颜色的异常。
第二步:修改MainActivity的点击逻辑
直接调用Adapter的更新方法即可,无需重新设置Adapter:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 此处替换为你自己的实际数据源 val countries = arrayOf("中国", "美国", "日本") val adapter = Countryadapter(countries, this, false) val recyclerView = findViewById<RecyclerView>(R.id.Recycler_view) recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = adapter val button = findViewById<Button>(R.id.Button_1) button.setOnClickListener { // 直接调用Adapter的更新方法触发刷新 adapter.updateColorState(true) Toast.makeText(this, "change color = true", Toast.LENGTH_SHORT).show() } }
内容的提问来源于stack exchange,提问作者Sirolf
相关产品推荐
相关产品推荐

