【问题标题】:How to get scroll current position upon CollectionChange event in Xamarin?如何在 Xamarin 中的 CollectionChanged 事件上滚动当前位置?
【发布时间】:2020-04-01 22:42:57
【问题描述】:

我有一个 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);
        };            
    }

谢谢大家!

【问题讨论】:

  • 您需要向我们展示相关代码。我们不知道您的 UI 是如何构建的,因此很难就如何实现您想要的功能提出任何建议。
  • 当然,杰森,谢谢你的提示!
  • 我试过了,但我无法使用这个“ScrollViewer”不知道从哪里得到它
  • 抱歉,这是一篇 WPF 帖子。
  • @Anand 我正在查看您建议的代码,它看起来像一个解决方案......但它比我需要的要多得多......我已经准备好了一切工作我只是不'不知道当 CollectionChanged 事件触发时如何获取滚动当前位置??如果我不明白这一点,那么我将重做我的方法并实施您建议的方法

标签: xamarin xamarin.forms screen visible items


【解决方案1】:

终于找到了获取滚动当前位置的方法!!

基本上,如果你有一个像我这样的 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];
    }

谢谢你们的提示,如果你喜欢我的回答,请随意投票:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多