【发布时间】:2019-01-22 17:40:05
【问题描述】:
我正在尝试创建一个在应用程序运行时添加日志的日志记录页面。 所需的一项功能是能够自动滚动到最新(最后)添加的日志。
问题是,当我在 observablecollection 上使用 scrollto 功能时,日志记录页面似乎会重新加载整个列表。
这不是问题,但是当列表足够大时,它会导致页面在重绘列表时闪烁。
是否无论如何都向页面添加日志语句并滚动到页面的最后一个元素而不会导致页面闪烁。
我确实支持任何解决方案,但它必须满足以下要求:
能够在创建/添加日志时实时刷新(频繁)
能够自动滚动到页面末尾。
能够干净地刷新(没有闪烁或其他类型的问题)。
我的尝试:
我尝试了两种不同的方法来实现这一点。
第一种方法是将“日志语句”(字符串)的标签添加到 内容页。然后我将使用 lastorDefault() 方法来查找布局中的最后一个子项(在本例中为 stacklayout) 然后滚动到该项目(在本例中为 Label())。
我必须使用 Device.BeginInvokeOnMainThread 将标签添加到主线程(否则它会与程序的其他方面发生冲突)这会导致滚动函数和此调用之间出现竞争条件,最终在列表为足够大。 这种方式的第二个问题是,当页面变得足够大并且我们正在添加语句时,它也会出现闪烁问题。
我尝试实现它的第二种方法是使用可观察集合,在该集合中我将标签添加到可观察集合并使用 用于访问标签文本和文本颜色的数据模板。添加标签后,我使用 scrollto 功能滚动到列表底部。 当列表很小(小于 150 个左右)时,这可以正常工作,但之后添加标签(日志语句)时页面会闪烁。
我目前的想法是在可观察集合中只包含最后 50 个左右的项目,这样刷新就干净了 我正在寻找更好的解决方案,但可能不存在。
我已经对显示的代码进行了大量修改,因此其中一些没有意义,但我已尝试保持此处的逻辑纯净。
我现在无法添加可编译的代码,但如果此代码不足,我将创建一个测试项目,请告诉我。
代码:
public LoggingPage()
{
InitializeComponent();
loggingPage.ItemAppearing += EnableAutoScroll;
DisplayLogsOnScreen(logstatements);
}
//adds the logs to the screen
private void DisplayLogsOnScreen(LogStatement logstatements)
{
Label loggingLabel = new Label();
foreach (typeOfLog tempLogType in differentlogTypes)
{
switch (tempLogType)
{
case typeOfLog.FIRSTTYPE:
Device.BeginInvokeOnMainThread(() => {
logObservableCollection.Add(loggingLabel);
});
break;
case LogType.SECONDTYPE:
Device.BeginInvokeOnMainThread(() => {
differentLogObservableCollection.Add(loggingLabel);
});
break;
default:
break;
}
}
}
// have to wrap the scrollto events in an itemAppeared event handler
// otherwise the update to the UI is laggy
// it still has issues updating the logview this workaround is not perfect
private void AddAutoScroll(object sender, EventArgs e)
{
if (autoScroll)//a button that enables and disables autoscroll
{
logListView.ScrollTo(logObservableCollection.LastOrDefault(), ScrollToPosition.End, true);
logListView.ScrollTo(differentLogObservableCollection.LastOrDefault(), ScrollToPosition.End, true);
}
}
Xaml:
<ContentPage Title="logPage">
<ContentPage.Content>
<ListView x:Name="loggingPage">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding Text}" TextColor="{Binding TextColor}"/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
【问题讨论】:
标签: c# .net xaml xamarin xamarin.forms