如何仅修改父RecyclerView第0项中嵌套RecyclerView的首个子元素
解决方案
要实现仅父RecyclerView第0项内的子RecyclerView首个元素加粗,核心是让子RecyclerView的Adapter知晓自己所属的父项位置,而非仅判断子项的position。
Kotlin 实现示例
1. 修改子Adapter,接收父项位置参数
class ChildAdapter( private val items: List<String>, private val parentPosition: Int // 新增父项位置参数 ) : RecyclerView.Adapter<ChildAdapter.ChildViewHolder>() { inner class ChildViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val tvItem: TextView = itemView.findViewById(R.id.tv_child_item) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChildViewHolder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.item_child, parent, false) return ChildViewHolder(view) } override fun onBindViewHolder(holder: ChildViewHolder, position: Int) { val itemText = items[position] holder.tvItem.text = itemText // 仅当父项是第0项,且子项是第0个时加粗 if (parentPosition == 0 && position == 0) { holder.tvItem.typeface = Typeface.DEFAULT_BOLD } else { holder.tvItem.typeface = Typeface.DEFAULT } } override fun getItemCount() = items.size }
2. 父Adapter绑定子RecyclerView时传入当前父项位置
class ParentAdapter(private val parentData: List<List<String>>) : RecyclerView.Adapter<ParentAdapter.ParentViewHolder>() { inner class ParentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val rvChild: RecyclerView = itemView.findViewById(R.id.rv_child) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ParentViewHolder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.item_parent, parent, false) return ParentViewHolder(view) } override fun onBindViewHolder(holder: ParentViewHolder, position: Int) { val childItems = parentData[position] // 创建子Adapter时传入当前父项的position val childAdapter = ChildAdapter(childItems, position) holder.rvChild.apply { layoutManager = LinearLayoutManager(context) adapter = childAdapter } } override fun getItemCount() = parentData.size }
适配复杂已有Adapter的方案
如果你的子Adapter已经比较复杂,不想修改构造函数,可以通过Setter方法传递父项位置:
修改后的子Adapter
class ChildAdapter(private val items: List<String>) : RecyclerView.Adapter<ChildAdapter.ChildViewHolder>() { private var parentPosition = -1 // 新增Setter方法设置父项位置 fun setParentPosition(pos: Int) { this.parentPosition = pos notifyDataSetChanged() // 触发列表更新 } inner class ChildViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val tvItem: TextView = itemView.findViewById(R.id.tv_child_item) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChildViewHolder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.item_child, parent, false) return ChildViewHolder(view) } override fun onBindViewHolder(holder: ChildViewHolder, position: Int) { val itemText = items[position] holder.tvItem.text = itemText if (parentPosition == 0 && position == 0) { holder.tvItem.typeface = Typeface.DEFAULT_BOLD } else { holder.tvItem.typeface = Typeface.DEFAULT } } override fun getItemCount() = items.size }
父Adapter中设置父项位置
override fun onBindViewHolder(holder: ParentViewHolder, position: Int) { val childItems = parentData[position] // 复用已有Adapter或创建新的 val childAdapter = holder.rvChild.adapter as? ChildAdapter ?: ChildAdapter(childItems) // 设置当前父项位置 childAdapter.setParentPosition(position) holder.rvChild.adapter = childAdapter }
关键说明
- 核心逻辑是同时判断父项位置和子项位置,避免仅通过子项position=0导致所有子列表首个元素加粗的问题。
- 由于RecyclerView存在ViewHolder复用机制,务必在父Adapter的
onBindViewHolder中确保子Adapter的父项位置被正确更新,避免复用旧的配置。
内容的提问来源于stack exchange,提问作者Altohombre
相关产品推荐
相关产品推荐

