首页 > 解决方案 > Fragment 没有接收到 ViewModel 发送的通道事件

问题描述

当我单击 DialogFragment 中的按钮时,我试图在 MainFragment 中显示 Snackbar。
当我从对话框类调用发送事件函数(在 ViewModel 中)时,什么也没有发生。我不知道我做错了什么,但在 MainFragment 中做类似事情的其他函数工作得很好。

在 ViewModel 中,clearInput()清除 MainFragment 中的 editText 的功能有效但onEditNoteClicked()不起作用,当我调用它时没有任何反应。

NoteOptionsDialog类:

@AndroidEntryPoint
class NoteOptionsDialog : BottomSheetDialogFragment() {

    private val viewModel: NotesViewModel by viewModels()

private fun setupClickListeners(view: View) {
        view.bottom_options_edit.setOnClickListener {
            viewModel.onEditNoteClicked()
            dismiss()
        }
    }  

NotesViewModel类:

@HiltViewModel
class NotesViewModel @Inject constructor(
    private val noteDao: NoteDao,
    private val preferencesManager: PreferencesManager,
    private val state: SavedStateHandle
) : ViewModel() {

private val notesEventChannel = Channel<NotesEvent>()
    val notesEvent = notesEventChannel.receiveAsFlow()

fun onSaveNoteClick() {

        val newNote = Note(noteText = noteText, noteLabelId = labelId.value)
        createNote(newNote)
    }

private fun createNote(newNote: Note) = viewModelScope.launch {
        noteDao.insertNote(newNote)
        clearInput()
    }

private fun clearInput() = viewModelScope.launch {
        notesEventChannel.send(NotesEvent.ClearEditText)
    }

fun onEditNoteClicked() = viewModelScope.launch {
        notesEventChannel.send(NotesEvent.ShowToast)
    }

fun onNoteSelected(note: Note, view: View) = viewModelScope.launch {
        notesEventChannel.send(NotesEvent.ShowBottomSheetDialog(note, view))
    }

sealed class NotesEvent {
        object ClearEditText : NotesEvent()
        object ShowToast : NotesEvent()  
        data class ShowBottomSheetDialog(val note: Note, val view: View) : NotesEvent()
    }  

NotesFragment类:

@AndroidEntryPoint
class NotesFragment : Fragment(R.layout.fragment_home), NotesAdapter.OnNoteItemClickListener,
    LabelsAdapter.OnLabelItemClickListener {

private val viewModel: NotesViewModel by viewModels()

override fun onViewCreated(view: View, savedInstanceState: Bundle?){
    super.onViewCreated(view, savedInstanceState)

    viewLifecycleOwner.lifecycleScope.launchWhenStarted {
            viewModel.notesEvent.collect { event ->
                when (event) {

                    is NotesViewModel.NotesEvent.ShowBottomSheetDialog -> {
                        NoteOptionsDialog().show(childFragmentManager, null)
                    }

                    is NotesViewModel.NotesEvent.ClearEditText -> {
                        et_home_note.text.clear()
                    }
                    is NotesViewModel.NotesEvent.ShowToast -> {
                        Snackbar.make(requireView(), "Snack!", Snackbar.LENGTH_LONG).show()
                    }
}

标签: androidkotlinmvvm

解决方案


找到了解决方案。对于片段,我应该使用by activityViewModels()而不是by viewModels()

private val viewModel: NotesViewModel by activityViewModels()

推荐阅读