Xamarin.forms - Trouble behaviour between ListView & keyboard

2020-02-27 listview xamarin.forms xamarin.android xamarin.ios keyboard

I'm workin' on an Xamarin.forms app chat and I'm havin' some troubles with the listView. The first one is that when I'm ready to type some message, the keyboard overlapps the main chat. The second one occurs when I hide the keyboard and the listView doesn't scroll all the away down. Is there some convention solution to this type of problems? Here's the video and the respective code:

VIDEO

My xaml Page:

  <StackLayout>


        <ListView 
                    x:Name="MessagesListView" 
                    ItemTemplate="{StaticResource MessageTemplateSelector}" 
                    ItemsSource="{Binding Pedidos}" 
                    HasUnevenRows="True"  SeparatorVisibility="None"  HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" IsEnabled="True" SelectionMode="None" BackgroundColor="{StaticResource BackGroundColor}"/>


        <StackLayout Orientation="Horizontal" BackgroundColor="{StaticResource white}" Grid.Row="1">

            <local1:CustomEntry 
                HorizontalOptions="FillAndExpand"  

                Placeholder="{translator:Translate Mensagem}"  
                Keyboard="Chat"  Margin="8,0,0,0" PlaceholderColor="{StaticResource PlaceHolderText}" TextColor="{StaticResource texto}"  FontSize="14" Text="{Binding Pedido.Message}" x:Name="Message"/>
            <Image Source="send.png" WidthRequest="32" HeightRequest="32" Margin="8,8,8,8" BackgroundColor="Transparent">
                <Image.GestureRecognizers>
                    <TapGestureRecognizer
                           Command="{Binding EnviarPedidoCommand}"
                           Tapped="Button_Clicked"
                            />
                </Image.GestureRecognizers>
            </Image>
        </StackLayout>

</StackLayout>

Backend page:

 public ChatPage(Classes.ClassConversation.ResultadoConversation conversation, Classes.ClassUser.Result user)
    {
        InitializeComponent();

        GetResult = conversation;
        ConnectionsStrings.GlobalVar.email = user.rowKey;
        GetUser = user;

        Xamarin.Forms.Application.Current.On<Xamarin.Forms.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);

        _viewModel = new ViewModels.ConnectionHub(conversation, user);

    }

    protected override async void OnAppearing()
    {

        base.OnAppearing();
        GetHistoryOfConversation(GetResult.rowKey, ConnectionsStrings.GlobalVar.Token, GetUser);

        BindingContext = _viewModel;

        await _viewModel.Connect();
    }

    protected override async void OnDisappearing()
    {
        base.OnDisappearing();
        await _viewModel.Disconnect();
    }

    //Limpa o campo mensagem quando envia mensagem
    private void Button_Clicked(object sender, EventArgs e)
    {
        Message.Text = "";     
    }

    //Função que recebe o historico de mensagens daquela conversa
    async void GetHistoryOfConversation(string conversationId, string token, Classes.ClassUser.Result user)
    {
        try
        {
            Classes.ClasMessage messages = await Servicos.Servicos.GetHistoryOfConversation(conversationId, token, user, GetResult);
            _viewModel.Pedidos = new ObservableRangeCollection<Classes.SendMessage>(messages.result);

            var target = _viewModel.Pedidos[_viewModel.Pedidos.Count - 1];
            MessagesListView.ScrollTo(target, ScrollToPosition.End, false);

            var result = await Servicos.Servicos.ReadConversation(conversationId, GetResult);
        }
        catch (Exception)
        {
            await DisplayAlert(Languages.AppResources.Notifications, Languages.AppResources.ErrorOccurred, "Ok");
        }
    }

Answers

The first one is that when I'm ready to type some message, the keyboard overlapps the main chat.

For the first question, you should detect the keyboard up/down and move up/down the listView.

In Android, you can use Soft Keyboard Input Mode

<Application ...
             xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
             android:Application.WindowSoftInputModeAdjust="Resize">
  ...
</Application>

In iOS , you need to write a custom renderer to detect the event.

You can check the answers in this thread and read this blog for solutions.

The second one occurs when I hide the keyboard and the listView doesn't scroll all the away down.

You should scroll the listView in the EnviarPedidoCommand after you insert that message to the itemSource of listView.

Related