Message List View Model

Last Edit: Oct 28 2020

MessageListViewModel works with MessageListView and uses StreamChatAndroidOffline library to communicate with Stream API.

The view model exposes two LiveData objects, as well as two values:

  • mode - distincts if the view is in thread mode, can be one of:

    • Thread

    • Normal

  • state - can be one of:

    • Loading

    • Result

    • NavigateUp

  • currentUser

  • channel

You can inform the view model about new events using onEvent method. Currently, MessageListViewModel supports the following events:

  • BaskButtonPressed

  • EndRegionReached

  • LastMessageRead

  • ThreadModeEntered

  • DeleteMessage

  • FlagMessage

  • GiphyActionSelected

  • RetryMessage

Creating Message List View Model

MessageListViewModel can be instantiated using ChannelViewModelFactory:


ChannelViewModelFactory factory = new ChannelViewModelFactory(channel.getCid());
MessageListViewModel viewModel = new ViewModelProvider(this, factory)
        .get(MessageListViewModel.class);
                    

private val viewModel: MessageListViewModel by viewModels {
    ChannelViewModelFactory(channel.cid)
}
                    

Binding with MessageListView

MessageListViewModel can be bound with MessageListView using MessageListViewModelBinding:


MessageListViewModelBinding.bind(viewModel, messageListView, lifecycle);
                    

viewModel.bindView(messageListView, viewLifecycleOwner)C
                    

Calling bind method results in:

  • Initializing view with the channel and current user

  • Displaying new messages

  • Setting:

    • EndRegionReachedHandler

    • LastMessageReadHandler

    • OnMessageDeleteHandler

    • OnStartThreadHandler

    • OnMessageFlagHandler

    • OnSendGiphyHandler

    • OnMessageRetryHandler

Handling back button press

MessageListViewModel contains a mechanism for handling back button behaviour when you're in a thread. If you want to use it, you need to override Activitiy's back button behaviour:


getOnBackPressedDispatcher().addCallback(lifecycleOwner, new OnBackPressedCallback(true) {
    @Override
    public void handleOnBackPressed() {
        messageListViewModel.onEvent(MessageListViewModel.Event.BackButtonPressed.INSTANCE);
    }
});
                    

onBackPressedDispatcher.addCallback(
    lifecycleOwner,
    object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            messageListViewModel.onEvent(MessageListViewModel.Event.BackButtonPressed)
        }
    }
)
                    

The view model will exit the thread if needed and emit MessageListViewModel.State.NavigateUp if user isn't inside a thread. You need to handle this state by yourself - for example, by finishing the current Activity:


messageListViewModel.getState().observe(lifecycleOwner, state -> {
    if (state instanceof MessageListViewModel.State.NavigateUp) {
        finish();
    }
});
                    

messageListViewModel.state.observe(lifecycleOwner) {
    when (it) {
        is MessageListViewModel.State.NavigateUp -> finish()
        else -> Unit
    }
}