如何阻止BottomSheetDialogFragment每次打开都重新加载?
解决BottomSheetDialogFragment重复创建及ViewModel重建问题
1. 复用Fragment实例,避免每次新建对象
每次点击都new ChatSheetFragment()必然会生成新的Fragment实例,触发完整生命周期。改成在宿主中保留实例引用,按需复用:
// 宿主Activity/Fragment中声明成员变量 private var chatSheetFragment: ChatSheetFragment? = null private fun chatButton() { binding.chatIv.setOnClickListener { if (chatSheetFragment == null) { chatSheetFragment = ChatSheetFragment() } // 检查是否已添加到FragmentManager,防止重复添加报错 if (!chatSheetFragment!!.isAdded) { chatSheetFragment!!.show( supportFragmentManager, ChatSheetFragment::class.java.simpleName ) } } }
如果需要在弹窗关闭后清理实例,可在ChatSheetFragment的onDismiss回调中置空宿主引用,避免内存泄漏:
// ChatSheetFragment内部 override fun onDismiss(dialog: DialogInterface) { super.onDismiss(dialog) (activity as? YourHostActivity)?.chatSheetFragment = null }
2. 让ViewModel绑定宿主生命周期
当前ViewModel绑定的是ChatSheetFragment的生命周期,Fragment重建ViewModel就会跟着重建。改成绑定宿主Activity或父Fragment的生命周期,确保ViewModel持久化:
// ChatSheetFragment中获取ViewModel时指定宿主 private val viewModel: ChatViewModel by viewModels( ownerProducer = { requireActivity() } // 绑定到宿主Activity生命周期 // 若宿主是Fragment,可改为 { requireParentFragment() } )
3. 优化RecyclerView数据加载逻辑
在ViewModel中缓存聊天数据,只在首次加载时获取,后续打开直接用缓存数据刷新UI:
class ChatViewModel @Inject constructor( private val chatRepository: ChatRepository ) : ViewModel() { private val _chatMessages = MutableLiveData<List<ChatMessage>>() val chatMessages: LiveData<List<ChatMessage>> = _chatMessages init { loadChatMessages() } private fun loadChatMessages() { viewModelScope.launch { // 仅ViewModel初始化时加载一次,如需刷新可调用refresh方法 val messages = chatRepository.getChatMessages() _chatMessages.postValue(messages) } } // 提供手动刷新接口,按需调用 fun refreshChatMessages() { loadChatMessages() } }
内容的提问来源于stack exchange,提问作者Syed Ibrahim
相关产品推荐
相关产品推荐

