Android RecyclerView点击条目时如何修改其他holder的视图背景
解决方案

问题根源
你当前的代码存在两个核心问题:
- 点击事件中直接遍历数据列表尝试修改其他条目样式是无效的,RecyclerView只会持有当前可见条目的Holder实例,不可见的条目你无法直接拿到对应实例修改样式
- 你在
onBind方法中将条目背景写死为灰色,每次Holder复用的时候都会覆盖你之前修改的背景状态,滑动后选中状态会直接错乱
修改步骤
1. Adapter新增选中位置记录变量
在Adapter类中新增成员变量记录当前选中的条目位置,默认值可以根据需求设置为0(默认选中第一个)或者-1(默认无选中)
private var selectedPosition = 0
2. 改造onBind方法的背景设置逻辑
不要写死背景样式,根据当前position是否为选中位置动态设置背景:
// 删掉原来固定写死灰色背景的代码,替换成下面的逻辑 if (position == selectedPosition) { linear_background.background = context.getDrawable(R.drawable.shape_white_gift_recycler_stroke) } else { linear_background.background = context.getDrawable(R.drawable.shape_gray_gift_recycler_stroke) }
3. 改造点击事件逻辑
点击时只需要更新选中位置,调用刷新方法让RecyclerView重新渲染所有可见条目即可,不需要手动遍历修改每个Holder的样式
setOnClickListener { val preSelectedPos = selectedPosition selectedPosition = position // 局部刷新新旧两个选中位置,性能优于全局刷新notifyDataSetChanged() notifyItemChanged(preSelectedPos) notifyItemChanged(selectedPosition) viewModel?.getBrandItemsResult(item[position].categorySeq) }
修改后完整代码
class GiftShowCategoryAdapterHolder(parent: ViewGroup) : RecyclerView.ViewHolder( LayoutInflater.from(parent.context).inflate(R.layout.item_giftshow_category, parent, false) ) { fun onBind(item: ArrayList<GiftCardResponse.brandCategories>, viewModel: GiftShowViewModel?, position: Int, selectedPosition: Int) { itemView.run { val displaymetrics = DisplayMetrics() (context as Activity).windowManager.defaultDisplay.getMetrics(displaymetrics) val devicewidth: Int = displaymetrics.widthPixels / 4 val deviceheight: Int = displaymetrics.heightPixels / 8 iv_giftshow_category.layoutParams.width = devicewidth iv_giftshow_category.layoutParams.height = deviceheight Glide.with(this).load(item[position].categoryIcon).error(R.drawable.choice_cash) .into(iv_giftshow_category) tv_giftshow_category.text = item[position].categoryName // 动态设置背景 if (position == selectedPosition) { linear_background.background = context.getDrawable(R.drawable.shape_white_gift_recycler_stroke) } else { linear_background.background = context.getDrawable(R.drawable.shape_gray_gift_recycler_stroke) } setOnClickListener { val preSelected = selectedPosition selectedPosition = position notifyItemChanged(preSelected) notifyItemChanged(selectedPosition) viewModel?.getBrandItemsResult(item[position].categorySeq) } } } } private var giftShowCategoryList = ArrayList<GiftCardResponse.brandCategories>() // 新增选中位置记录 private var selectedPosition = 0 private var viewModel: GiftShowViewModel? = null override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = GiftShowCategoryAdapterHolder(parent); override fun getItemCount() = giftShowCategoryList.size override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { (holder as? GiftShowCategoryAdapterHolder)?.onBind(giftShowCategoryList, viewModel, position, selectedPosition) } fun addItem(items: List<GiftCardResponse.brandCategories>) { giftShowCategoryList = items as ArrayList<GiftCardResponse.brandCategories> } fun addViewModel(viewModel: GiftShowViewModel) { this.viewModel = viewModel }
内容的提问来源于stack exchange,提问作者Duseop
相关产品推荐
相关产品推荐

