RecyclerView Adapter中设置子项条件可见性:应在onCreateViewHolder还是onBindViewHolder中操作?
结论:推荐在
onCreateViewHolder中设置按钮可见性 你的做法其实是完全正确的,结合你的场景(整个Adapter要么是管理员模式,要么是普通用户模式,所有条目权限一致),在onCreateViewHolder里设置按钮可见性是最优选择,原因如下:
1. 性能更优
onCreateViewHolder只会在ViewHolder首次创建时调用,每个ViewHolder实例只会执行一次这个方法;而onBindViewHolder会在**每次条目绑定(包括ViewHolder复用)**时触发,频繁重复设置可见性属于无意义的冗余操作。虽然设置可见性本身不算“繁重操作”,但遵循“尽量减少onBindViewHolder中的非必要操作”的原则,能避免潜在的性能损耗(尤其是列表条目较多时)。
2. 符合你的业务逻辑
你的isAdmin参数是在Adapter初始化时传入的,意味着整个列表的所有条目都遵循同一套权限规则——要么所有条目都显示删除按钮,要么都隐藏。这种全局统一的配置,完全不需要在每个条目绑定的时候重复判断,一次设置即可覆盖所有复用的ViewHolder。
针对你的代码的小优化
目前的代码逻辑没问题,但可以把ViewHolder的事件绑定和视图初始化逻辑封装到ViewHolder内部,让代码更清晰:
class NoticesAdapter( options: FirestoreRecyclerOptions<NoticeModel>, private val isAdmin: Boolean, private val listener: INoticeListAdapter ) : FirestoreRecyclerAdapter<NoticeModel, NoticesAdapter.NoticeViewHolder>(options) { inner class NoticeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val noticeText: TextView = itemView.findViewById(R.id.noticeText) val noticeAuthor: TextView = itemView.findViewById(R.id.noticeAuthor) val noticePostDate: TextView = itemView.findViewById(R.id.noticePostDate) val noticePostTime: TextView = itemView.findViewById(R.id.noticePostTime) val deleteNoticeBtn: Button = itemView.findViewById(R.id.deleteNoticeBtn) init { // 初始化时设置按钮可见性 if (!isAdmin) { deleteNoticeBtn.visibility = View.GONE } // 绑定点击事件,增加位置有效性判断避免异常 deleteNoticeBtn.setOnClickListener { val position = adapterPosition if (position != RecyclerView.NO_POSITION) { val noticeSnapshot = snapshots.getSnapshot(position) listener.deleteNoticeBtnListener(noticeSnapshot) } } } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoticeViewHolder { val noticeListView = LayoutInflater.from(parent.context) .inflate(R.layout.item_notice, parent, false) return NoticeViewHolder(noticeListView) } override fun onBindViewHolder(holder: NoticeViewHolder, position: Int, model: NoticeModel) { holder.noticeText.text = model.noticeText holder.noticeAuthor.text = MyUtils.getUserName() holder.noticePostDate.text = model.datePosted holder.noticePostTime.text = model.timePosted } }
例外情况:什么时候需要用onBindViewHolder?
如果未来你的业务需求变化,比如列表中不同条目对应不同权限(比如有的条目是管理员自己发的能删除,有的是普通用户发的不能删),此时权限不再是全局参数,而是每个条目的属性,这时候才需要在onBindViewHolder中根据当前条目的数据动态设置按钮可见性。
内容的提问来源于stack exchange,提问作者AMAN KUMAR
相关产品推荐
相关产品推荐

