我们有一个即时消息应用程序。我们希望在收到消息时自动滚动,以便显示新消息。当前,当收到需要滚动的第一条消息时,页面不会滚动。也就是说,新消息隐藏在输入控件后面。它需要另一条消息或用户调整滚动视图,然后才能正常工作。
我们的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>
我们调用滚动的代码如下所示:
public void ScrollMessagesToEnd()
{
StackLayout messagesContent = (messagesScrollView.Content as StackLayout);
var frame = messagesContent.Children.LastOrDefault();
if (frame != null)
{
messagesScrollView.ScrollToAsync(frame, ScrollToPosition.MakeVisible, true);
}
}
答案 0 :(得分:2)
无论采用何种解决方案,都应将ScrollMessagesToEnd
设为异步,您需要await
ScrollToAsync()
。由于您现在正在等待ScrollToAsync()
,我建议在UI线程上明确地运行它。
之后,完成后,您可以尝试将await Task.Delay(300)
添加到方法的顶部,我之前必须这样做。
您可能还想尝试启用和禁用我发现可以影响滚动但在每个平台上测试它的动画,因为每个平台的效果可能会有所不同。
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
}
}
答案 1 :(得分:2)
我强烈建议不要使用嵌套滚动视图,但如果你保留它们,那么这里是解决方案。
相反
messagesScrollView.ScrollToAsync(frame, ScrollToPosition.MakeVisible, true);
使用
mainScrollView.ScrollToAsync(frame, ScrollToPosition.End, true);
或
mainScrollView.ScrollToAsync(frame, ScrollToPosition.MakeVisible, true);