Как получить текущую позицию прокрутки на событие CollenctionChange, Xamarin - PullRequest
0 голосов
/ 02 апреля 2020

У меня есть приложение чата Xamarin, когда я получаю новые сообщения, оно прокручивается до последнего полученного сообщения. Я хочу, чтобы это произошло, если я вижу обязательные последние сообщения, в противном случае, если пользователь прокручивает старые сообщения и приходит новое сообщение, я хочу, чтобы мне показывали кнопку (как в команде) со словом «новый», и если вы нажимаете прокрутку к последнему сообщению.

Проблема здесь в том, что для этого я должен иметь возможность узнать, какие сообщения пользователь видит на экране, хотя бы знать сообщение на нижнем экране или просто прокрутить текущую позицию! Зная, что я могу сделать все остальное самостоятельно.

Это мой метод OnAppearing:

    protected override void OnAppearing()
    {
        base.OnAppearing();

        if (viewModel.Messages.Count == 0)
        {
            viewModel.LoadItemsCommand.Execute(null);
        }

        viewModel.Messages.CollectionChanged += (sender, e) =>
        {
            //GET SCROLL CURRENT POSITION HERE!
            var target = viewModel.Messages[viewModel.Messages.Count - 1];

            ItemsListView.ScrollTo(target, ScrollToPosition.End, false);
        };            
    }

Спасибо всем!

1 Ответ

0 голосов
/ 05 апреля 2020

Наконец-то я нахожу способ получить текущую позицию прокрутки !!

В принципе, если у вас есть ListView, такой как я, когда он по умолчанию уже содержит прокрутку, вы можете просто сделать это так:

        YourListViewName.Scrolled += (sender, e) =>
        {
            var scrollCurrentVerticalPosition = e.ScrollY;                
        };

В моем случае вместо вызова внутри события CollectionChanged мне пришлось сделать следующее:

Создать личную переменную:

private bool scrollPositionEnd = true;

А внутри метода OnAppearing:

protected override void OnAppearing()
{
    base.OnAppearing();

    if (viewModel.Messages.Count == 0)
    {
        viewModel.LoadItemsCommand.Execute(null);
    }

    viewModel.Messages.CollectionChanged += (sender, e) =>
    {            
        if (scrollPositionEnd == true)
        {
            ScrollToEnd();
        }
        else if (GetLastMessage().UserId != UserId) //so it wont trigger on your own messages
        {
            NewMessagesButton.IsVisible = true;
        }
    };    

    ItemsListView.Scrolled += (sender, e) =>
    {
        if (e.ScrollY == 0) //when scroll is in bottom ScrollY value is 0 
        {
            scrollPositionEnd = true;

            //if you manually scroll down until the new message
            NewMessagesButton.IsVisible = false;
        }
        else
        {
             scrollPositionEnd = false;
        }
    };
 }

Вспомогательные методы:

    //If you click the button event
    private void ButtonScrollClick(object sender, EventArgs e)
    {
        ScrollToEnd();
    }

    private void ScrollToEnd()
    {
        NewMessagesButtonFrame.IsVisible = false;
        Message target = GetLastMessage();
        ItemsListView.ScrollTo(target, ScrollToPosition.End, false);
    }

    private Message GetLastMessage()
    {
        return viewModel.Messages[viewModel.Messages.Count - 1];
    }

Спасибо вам, ребята, за ваши советы, и если вам понравился мой ответ, напишите нам:)

...