Firestore新增数据后Adapter未更新:notifyItemInserted无效
问题排查与修复方案
核心问题1:错误创建Fragment实例
你在监听器里每次都调用fragment_chat()创建新的Fragment对象,这个新实例并未加入Activity的视图层级,它的view为null,调用updateBoardToUi根本无法更新界面上的RecyclerView。
修复:
在MainActivity中保留已加载的ChatFragment引用,通过ID或Tag获取:
// 假设Fragment在布局中的id为fragment_chat val chatFragment = supportFragmentManager.findFragmentById(R.id.fragment_chat) as? fragment_chat // 监听器内调用该引用的方法 chatFragment?.updateBoardToUi(Constans.BOARDS_CHATS_LIST)
核心问题2:重复创建Adapter导致notify无效
updateBoardToUi每次都会新建BoardItemsAdapter,再调用notifyItemInserted(0)——但新Adapter初始化时已持有完整数据集,notifyItemInserted是通知新增条目,和SnapshotListener返回全量文档的逻辑不符,同时重复创建Adapter会浪费性能、丢失状态。
修复:
在Fragment的onViewCreated中仅初始化一次Adapter,后续仅更新数据集并通知刷新:
// Fragment成员变量声明Adapter private lateinit var adapter: BoardItemsAdapter override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val context = requireContext() // 仅初始化一次RecyclerView配置 view.rv_chats_list.layoutManager = LinearLayoutManager(context) view.rv_chats_list.setHasFixedSize(true) // 初始化空数据集的Adapter adapter = BoardItemsAdapter(context, ArrayList()) view.rv_chats_list.adapter = adapter // 提前设置点击监听 adapter.setOnClickListener(object : BoardItemsAdapter.OnClickListener { override fun onClick(position: Int, model: Board) { val intent = Intent(context, ChatActivity::class.java) intent.putExtra(Constans.BOARD_CHAT_DETAILS, model) intent.putExtra("uid", FirebaseAuth.getInstance().currentUser?.uid ) intent.putExtra(Constans.DOCUMENT_ID, model.documentId) intent.putExtra("position", position) startActivity(intent) } }) } // 修改updateBoardToUi方法 fun updateBoardToUi(boardsChatsList: ArrayList<Board>) { if(boardsChatsList.size > 0){ view?.rv_chats_list?.visibility = View.VISIBLE view?.no_chats_avlible?.visibility = View.GONE // 更新Adapter数据集 adapter.updateData(boardsChatsList) // 通知数据变更 adapter.notifyDataSetChanged() // 追求性能可替换为DiffUtil计算差异后局部刷新 }else{ view?.no_chats_avlible?.visibility = View.VISIBLE view?.rv_chats_list?.visibility = View.GONE } }
给BoardItemsAdapter添加数据集更新方法:
class BoardItemsAdapter(private val context: Context, private var boardsList: ArrayList<Board>) : RecyclerView.Adapter<...>() { // ... 其他原有方法 fun updateData(newList: ArrayList<Board>) { boardsList.clear() boardsList.addAll(newList) } }
额外优化:移除全局常量依赖
Constans.BOARDS_CHATS_LIST作为全局变量易引发数据不一致,建议直接传递数据集给Fragment:
// MainActivity监听器内修改 val boards = ArrayList<Board>() for (doc in value!!) { val board = doc.toObject(Board()::class.java) boards.add(board) } chatFragment?.updateBoardToUi(boards)
内容的提问来源于stack exchange,提问作者Elchanan Elsner
相关产品推荐
相关产品推荐

