Android Kotlin中Fragment属性传入Adapter后调用修改方法不生效问题
问题原因
- Boolean是值类型,你在构造
PostsAdapter时传入的selectionMode是当前Fragment中变量的值拷贝,Adapter内部会单独存储这个Boolean值,和Fragment中的原变量没有关联 - 后续点击列表调用
enableSelectionMode()仅修改了Fragment中的selectionMode值,Adapter内部存储的旧值没有任何变化,所以notifyDataSetChanged()后界面还是按旧值渲染,看不到效果
解决方案
这里提供最简便的修改方案,不需要改动现有架构逻辑:
- 修改Adapter构造,将固定的Boolean参数替换为获取最新选择状态的回调函数
- Adapter中所有用到选择状态的地方,都通过回调获取最新值,不存储固定拷贝
修改后的Adapter代码
class PostsAdapter( private val posts: List<Post>, private val model: PostsViewModel, // 替换为取值回调,不存储固定Boolean值 private val getSelectionMode: () -> Boolean, private val enableIt: () -> Unit ) : RecyclerView.Adapter<PostsAdapter.ViewHolder>() { companion object { private const val TYPE_FROM = 0 private const val TYPE_TO = 1 } inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { var postContent: TextView = itemView.findViewById(R.id.post_content) var selectPostCheckBox: ImageView = itemView.findViewById(R.id.post_select_checkbox) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context) .inflate( if (viewType == TYPE_TO) R.layout.to_post else R.layout.from_post, parent, false ) return ViewHolder(view) } @SuppressLint("CheckResult") override fun onBindViewHolder(holder: ViewHolder, position: Int) { // 通过回调获取最新的选择状态 val currentSelectionMode = getSelectionMode() holder.selectPostCheckBox.visibility = if (currentSelectionMode) View.VISIBLE else View.GONE holder.postContent.text = currentSelectionMode.toString() holder.selectPostCheckBox.setImageResource(R.drawable.cursor_color) holder.itemView.setOnClickListener() { enableIt() notifyDataSetChanged() } } override fun getItemCount() = posts.size override fun getItemViewType(position: Int): Int { return posts[position].selfPost } }
修改后的Fragment初始化Adapter代码
model.posts.observe(viewLifecycleOwner, { items -> recyclerView.adapter = PostsAdapter(items, model, // 传入回调,每次调用返回当前Fragment中selectionMode的最新值 { selectionMode }, ::enableSelectionMode) })
可选优化建议
- 不要每次
posts数据变化都新建Adapter,建议全局初始化一次Adapter,给Adapter新增submitList(List<Post>)方法更新数据,避免不必要的性能损耗 - 可以将
selectionMode放到PostsViewModel中存储,使用LiveData<Boolean>包裹,状态变化时自动通知界面更新,更符合MVVM架构规范
内容的提问来源于stack exchange,提问作者Jackson
相关产品推荐
相关产品推荐

