Message List View Model

LAST EDIT Feb 16 2021

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 ModelCopied!

MessageListViewModel can be instantiated using ChannelViewModelFactory:

1
2
3
ChannelViewModelFactory factory = new ChannelViewModelFactory(channel.getCid()); 
MessageListViewModel viewModel = new ViewModelProvider(this, factory) 
        .get(MessageListViewModel.class);
1
2
3
private val viewModel: MessageListViewModel by viewModels { 
    ChannelViewModelFactory(channel.cid) 
}

Binding with MessageListViewCopied!

MessageListViewModel can be bound with MessageListView using MessageListViewModelBinding:

1
MessageListViewModelBinding.bind(viewModel, messageListView, lifecycle);
1
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 pressCopied!

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:

1
2
3
4
5
6
getOnBackPressedDispatcher().addCallback(lifecycleOwner, new OnBackPressedCallback(true) { 
    @Override 
    public void handleOnBackPressed() { 
        messageListViewModel.onEvent(MessageListViewModel.Event.BackButtonPressed.INSTANCE); 
    } 
});
1
2
3
4
5
6
7
8
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:

1
2
3
4
5
messageListViewModel.getState().observe(lifecycleOwner, state -> { 
    if (state instanceof MessageListViewModel.State.NavigateUp) { 
        finish(); 
    } 
});
1
2
3
4
5
6
messageListViewModel.state.observe(lifecycleOwner) { 
    when (it) { 
        is MessageListViewModel.State.NavigateUp -> finish() 
        else -> Unit 
    } 
}