简体   繁体   English

Xamarin Forms ScrollView无法正确滚动

[英]Xamarin Forms ScrollView is not scrolling correctly

We have an instant message app. 我们有一个即时消息应用程序。 We want to scroll automatically when a message is received so the new message is visible. 我们希望在收到消息时自动滚动,以便显示新消息。 Currently, when the first message that requires scrolling is received, the page does not scroll. 当前,当收到第一条需要滚动的消息时,页面不会滚动。 That is, the new message is hidden behind our input controls. 也就是说,新消息隐藏在我们的输入控件后面。 It requires another message or the user to adjust the scrollview and then it works properly. 它需要另一条消息或用户调整滚动视图,然后它才能正常工作。

Our xaml is something like this: 我们的xaml是这样的:

<ContentPage>
  <StackLayout x:Name="mainStackLayout">
    <customControls:NavBar />
    <ScrollView x:Name="mainScrollView">
      <StackLayout x:Name="mainScrollViewStackLayout">
        <ScrollView x:Name="messagesScrollView">
          <StackLayout x:Name="messagesScrollViewContentStackLayout">
            <!-- Messages are programmatically inserted here -->
          </StackLayout>
        </ScrollView>
      </StackLayout>
    </ScrollView>
    <StackLayout>
      <!-- a couple buttons/inputs for sending messages -->
    </StackLayout>
  </StackLayout>
</ContentPage>

And the code we call to scroll looks like this: 我们调用滚动的代码如下所示:

public void ScrollMessagesToEnd()
{

    StackLayout messagesContent = (messagesScrollView.Content as StackLayout);
    var frame = messagesContent.Children.LastOrDefault();

    if (frame != null)
    {
            messagesScrollView.ScrollToAsync(frame, ScrollToPosition.MakeVisible, true);
    }
}

Regardless of the solution, ScrollMessagesToEnd should be made async and you need to await ScrollToAsync() . 无论采用哪种解决方案,都应使ScrollMessagesToEnd异步,并且您需要await ScrollToAsync() Since you are now awaiting ScrollToAsync() , I would suggest explicitly running it on the UI thread. 由于您现在正在等待ScrollToAsync() ,因此建议您在UI线程上显式运行它。

After that, is done, you might try adding await Task.Delay(300) to the top of your method, I have had to do that before. 之后,您可以尝试将await Task.Delay(300)添加到方法的顶部,我之前必须这样做。

You may also want to try enabling and disabling animation which I have found can effect scrolling but test it on each platform since the effect will probably be different on each. 您可能还想尝试启用和禁用动画,我发现它们可以影响滚动效果,但是在每个平台上都要进行测试,因为每个平台上的效果可能会有所不同。

public async Task ScrollMessagesToEndAsync() //Adding Async to method name, also try to return Task and await this method in the calling code as well
{
    await Task.Delay(300); //Sometimes code runs too fast and a delay is needed, you may test whether only a specific platform needs the delay

    StackLayout messagesContent = (messagesScrollView.Content as StackLayout);
    var frame = messagesContent.Children.LastOrDefault();

    if (frame != null)
    {
        Device.BeginInvokeOnMainThread(async () => await messagesScrollView.ScrollToAsync(frame, ScrollToPosition.MakeVisible, true)); //You could try passing in false to disable animation and see if that helps
    }
}

I would strongly recommend NOT use nested scroll views but if you keep them then here is the solution. 我强烈建议不要使用嵌套的滚动视图,但是如果保留它们,那么这里就是解决方案。

Instead 代替

messagesScrollView.ScrollToAsync(frame, ScrollToPosition.MakeVisible, true);

Use 采用

mainScrollView.ScrollToAsync(frame, ScrollToPosition.End, true);

or 要么

mainScrollView.ScrollToAsync(frame, ScrollToPosition.MakeVisible, true);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM