You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin中Fragment属性传入Adapter后调用修改方法不生效问题

问题原因
  • Boolean是值类型,你在构造PostsAdapter时传入的selectionMode是当前Fragment中变量的值拷贝,Adapter内部会单独存储这个Boolean值,和Fragment中的原变量没有关联
  • 后续点击列表调用enableSelectionMode()仅修改了Fragment中的selectionMode值,Adapter内部存储的旧值没有任何变化,所以notifyDataSetChanged()后界面还是按旧值渲染,看不到效果
解决方案

这里提供最简便的修改方案,不需要改动现有架构逻辑:

  1. 修改Adapter构造,将固定的Boolean参数替换为获取最新选择状态的回调函数
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 07:24:03