html - 在 xamarin 表单中加载页面后,HTML 标签文本不会呈现
问题描述
我们在 xamarin 表单应用程序中使用Xam.Plugin.HtmlLabel插件。当我们在构造函数中设置html字符串时,html标签在ios中正确加载。但是我们在方法中分配了相同的标签并在构造函数中调用了该方法,它没有在 iOS 中加载,而在 android 中它工作正常。问题重现的代码片段如下所述。此问题仅在 iOS 中发生。
HTMLPage.xaml
<ContentPage.Content>
<Grid>
<ScrollView
Padding="24"
HorizontalScrollBarVisibility="Never"
VerticalScrollBarVisibility="Never">
<htmlLabel:HtmlLabel
Text="{Binding HTMLDescription}"
LinkColor="{StaticResource LinkColor}"
TextColor="{StaticResource PriTextColor}" />
</ScrollView>
</Grid>
</ContentPage.Content>
HTMLPage.xaml.cs
private string htmlDescription;
public string HTMLDescription
{
get { return htmlDescription; }
set { htmlDescription = value; OnPropertyChanged(); }
}
public HTMLPage(string Description)
{
InitializeComponent();
GetHTML(Description);
BindingContext = this;
}
private async void GetHTML(string description)
{
await Task.Delay(2000); //This delay is for getting the data from server.
HTMLDescription = description;
}
解决方案
在任何代码中new HTMLPage("this is some html")
,您都在 UI 线程上吗?
如果不在 UI 线程上,那么这就是您的问题 - 在 UI 线程之外处理 UI 元素是有问题的。
如果在 UI 线程上运行,那么您会遇到不同的问题:构造函数是“阻塞”操作 - 在构造函数内部调用的代码上进行异步/等待是没有好处的;UI 线程被阻塞,直到构造函数返回!一般来说,在那里做任何冗长的事情都是个坏主意。最坏的情况是,Web 查询可能会延迟到超时。
相反,尝试在页面出现后设置 HTMLDescription:
// Hold it until used.
string Description;
public HTMLPage(string description)
{
this.Description = description;
...
}
protected override void OnAppearing()
{
base.OnAppearing();
// Move to background, so OnAppearing can return.
Task.Run(() => {
// Potentially long operation.
var html = GetHTML(Description);
// Move to UI thread, before touching any UI element.
Device.BeginInvokeOnMainThread(() => {
HTMLDescription = html;
}
}
}
private string GetHTML(string description)
{
Task.Delay(2000); //This delay is for getting the data from server.
return description;
}
注意:我已经从这个版本的 GetHTML 中删除了 async/await,因为它只在后台线程上调用。如果需要,您可以将它们放回原处。
当然,这样做的缺点是页面最初出现时没有该标签。如果您不希望这样,那么您需要GetHTML(...)
在调用构造函数之前改为。
所以你的代码(在你不显示的地方)会是这样的:
var html = GetHTML(...);
new HTMLPage(html);
因此,您回到了有效的原始案例,在构造函数中您已经有了 html 字符串,所以可以简单地做
HTMLDescription = description;
这就引出了一个问题:你为什么一开始不这样做?为什么将调用 GetHtML 放在构造函数中?
推荐阅读
- javascript - NodeJS 第二篇文章返回 NaN
- reactjs - 如何处理 Material UI onRowDeselected
- jira-xray - 如何使用 Python“请求”和 API 密钥将 RobotFramework 测试结果导入 XRAY?
- git - 如何构建 git 以在项目之间使用可交换的“模块”?
- javascript - 基于从下拉菜单中选择的文本字段的javascript验证
- arrays - C将宏作为参数指针传递
- react-native - React Navigation:从嵌套的堆栈导航器中隐藏标签栏
- python - Python 同时使用线程和异步?还是另一种解决方案?
- java - Kotlin CI 测试期间的静态最终变量初始化(Java 中)不正确
- json - 使用 ASN.1 而不是 JSON 或 Protobuf 构建微服务?