Press "Enter" to skip to content

Exploring a Chat UI in Xamarin Forms (Part. 1)

When developing a chat UI in Xamarin Forms there are a few challenges we face:

  • Having multiple UI cells
  • Put the chat entry in the top of the keyboard when focused
  • Multiple line expandable entry
  • Scroll to last when sending a message

This will be a series of articles were we are going to create a chat UI that tackles these challenges. In this part we are going to focus in the first two:

  • Having multiple UI cells
  • Put the chat entry in the top of the keyboard when focused

Let’s start by creating our application Models and ViewModels to handle our messages.

1-Create your Message model

The User property is to indicate which user send the message

2-Create your ViewModel

To handle the properties change in our ViewModel we are going to use the package PropertyChanged.Fody which basically will handle the property change notifications for us (You can find more info about it here https://blog.verslu.is/xamarin/keeping-dry-with-propertychanged-fody-for-xamarin-forms/).

After that we are going to create an ObservableCollection of our Message model. Then let’s create a new ICommand called OnSendCommand which will be executed by the view each time the user press the send message button. The execution code block of this command will add the text typed by the user to the Messages collection.

At this moment we are not connected to any API, so we are going to create an static variable in our App.cs for the User. Just to simulate the actual user.

public static string User = "Rendy"; 

Then will add some hard coded data to simulate a few messages received.

Let’s go with our first challenges:

1- Having multiple UI cells

In this scenario we have two types of cells, one blue to show the message received and one gray to show the message sent by the current user.

To achieve that, one option might be to play with the margins/ colors, etc according to which type is.

But a better approach is to use a DataTemplateSelector so that we can use a different cell according to the type.

We can achieve this easily:

  • Create a new class for each cell

  • Do the specific UI for each


  • Create a template selector

We are going to create a new class for our template selector, which basically will decide when to show each cell.

In this case we are going to show the IncomingCell when the user is different from our actual hardcoded user.

  • Use the template selector
    Now we are going to create the XAML for our chat page by first adding our template selector to the ResourceDictionary.
  <ContentPage.Resources>
        <ResourceDictionary>
            <local:ChatTemplateSelector x:Key="MessageTemplateSelector"/>
        </ResourceDictionary>
    </ContentPage.Resources>

As page content we will use a grid layout to render our views:

 <Grid RowSpacing="0" 
           ColumnSpacing="0">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="1" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
         <!--   OUR CHAT VIEWS HERE   -->
</Grid>

We want the first row to take all the space available because is where we are going to show our messages. Then we will use a fixed height of 1 for a separator between our list of messages and our typing view. Last but not least will have our typing view that we set as Auto because we want it to be the same height of this view conent.

In our first row will add a ListView to render our messages, we will indicate that the ItemTemplate to use will be the MessageTemplateSelector we added before.

   <ListView Grid.Row="0" 
                 ItemTemplate="{StaticResource MessageTemplateSelector}" 
                 ItemsSource="{Binding Messages}" 
                 Margin="0" 
                 HasUnevenRows="True" 
                 VerticalOptions="FillAndExpand" 
                 SeparatorColor="Transparent" >
    </ListView>

Our second row will be a BoxView just to represent the separation between our list of messages and our typing view

 <BoxView HorizontalOptions="FillAndExpand"
                 HeightRequest="1"
                 BackgroundColor="LightGray"
                 Grid.Row="1"/>

Finally on the last row, we add our typing view called ChatInputBarView which is a ContentView that contains a Entry to type the text of the message we want to send and a Label called “Send” with a TapGestureRecognizer so that we are able to tap it when we want to send our message.

 <partials:ChatInputBarView Grid.Row="2"
                                   Margin="0,0,10,0"/>

Our chat XAML:

Our ChatInputBarView XAML:

2- Put the chat entry on the top of the keyboard when focused

The normal behaviour when using a chat application, is that when the keyboard appears it should display text typing view above it.

To achieve this in Android we don’t need anything, by default it handles it. But on iOS it doesn’t, so we need a custom renderer to handle this behaviour.

Is important to mention that we are going to create a renderer for the complete text typing view not just for the entry. Why? Because our chat UI also has a send label, we want to raise up the view that contains both.

ContentView Renderer:

This renderer basically observes when the keyboard hides or show. Then based on the keyboard state we are going to add a margin to the view according the keyboard height.

Check the full source code here:

https://github.com/rdelrosario/ChatUIXForms

See you in the second part. Were we will cover:

  • Multiple line expandable entry
  • Scroll to last when sending a message

Happy chat!

11 Comments

  1. Dominik Dominik

    Thanks for this great and comprehensive article!

  2. Vishnu teja Vishnu teja

    Good

  3. Hey, do you know how to make it good looking when for example i add stacklayout on the top of the page ? To make scroll up only chat and other elements stay in the same position ?

    • Brandon Brandon

      I have this same issue. Let me know if you resolve it.

  4. Hey,

    Thanks for this great guidance.

    When is the the second part coming? I really need some help with implementing the
    “Scroll to last when sending a message” function.

  5. Brandon Brandon

    There are different ways to handle it, but this is the route that I took. I am also waiting for the 2nd part as the 1st part was very helpful.

    In your page code:
    protected override OnAppearing() {
    // Subscribe to scroll message from view model.
    MessagingCenter.Subscribe(this, “ScrollToBottom”, ScrollToBottom);
    }

    protected override OnDisappearing() {
    // Unsubscribe from scroll message from view model.
    MessagingCenter.Unsubscribe(this, “ScrollToBottom”);
    }

    // Method for handling scroll
    private void ScrollToBottom(ChatPageViewModel viewModel) {
    var itemToScrollTo = _viewModel.Messages.LastOrDefault();
    _listView.ScrollTo(itemToScrollTo, ScrollToPosition.MakeVisible, animated: true);
    }

    From the view model after sending the message and adding it to the listview:
    // Send scroll message to subscribers
    MessagingCenter.Send(this, “ScrollToBottom”);

  6. Jay Thaker Jay Thaker

    Hey Rendy, Man you are awesome!!!

    Thank you so much for all the efforts you put in to create such a wonderful resource! This really helped me a lot..

  7. ziya shaik ziya shaik

    Great work man…you are a saviour…Thanks alot 🙂

  8. Bibek Bibek

    awesome worm man .. Thanks for such nice post.. helped a lot.

Comments are closed.