我创建了一个试图从一组标签中解析超链接的类,它似乎可以识别超链接,但从未将标签中的正确跨度更改为超链接。我首先尝试:
public class HtmlLabelConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var formatted = new FormattedString();
foreach (var item in ProcessString((string)value))
formatted.Spans.Add(CreateSpan(item));
return formatted;
}
private Span CreateSpan(StringSection section)
{
var span = new Span()
{
Text = section.Text
};
if (!string.IsNullOrEmpty(section.Link))
{
span.GestureRecognizers.Add(new TapGestureRecognizer()
{
Command = _navigationCommand,
CommandParameter = section.Link
});
span.TextColor = Color.Blue;
span.TextDecorations = TextDecorations.Underline;
}
return span;
}
public IList<StringSection> ProcessString(string rawText)
{
const string spanPattern = @"(<a.*?>.*?</a>)";
MatchCollection collection = Regex.Matches(rawText, spanPattern, RegexOptions.Singleline);
var sections = new List<StringSection>();
var lastIndex = 0;
foreach (Match item in collection)
{
var foundText = item.Value;
sections.Add(new StringSection() { Text = rawText.Substring(lastIndex, item.Index) });
lastIndex += item.Index + item.Length;
// Get HTML href
var html = new StringSection()
{
Link = Regex.Match(item.Value, "(?<=href=\\\")[\\S]+(?=\\\")").Value,
Text = Regex.Replace(item.Value, "<.*?>", string.Empty)
};
sections.Add(html);
}
sections.Add(new StringSection() { Text = rawText.Substring(lastIndex) });
return sections;
}
public class StringSection
{
public string Text { get; set; }
public string Link { get; set; }
}
private ICommand _navigationCommand = new Command<string>((url) =>
{
//Device.OpenUri(new Uri(url));
Launcher.TryOpenAsync(new Uri(url));
});
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
与xaml中的<Label x:Name="labelParagraph"
FormattedText="{Binding Paragraph, Converter={StaticResource HtmlLabelConverter}}"/>
和格式如下的文本<a href="www.google.com"> link </a>
,它从文本中删除了<a href>
部分,但没有将link
变成超链接。这告诉我它正在查找超链接,但由于某种原因未执行该命令。其次,我尝试了以下自定义标签:
public class LinksLabel : Label
{
public static BindableProperty LinksTextProperty = BindableProperty.Create(nameof(LinksText), typeof(string), typeof(LinksLabel), propertyChanged: OnLinksTextPropertyChanged);
private readonly ICommand _linkTapGesture = new Command<string>((url) => Device.OpenUri(new Uri(url)));
public string LinksText
{
get => GetValue(LinksTextProperty) as string;
set => SetValue(LinksTextProperty, value);
}
private void SetFormattedText()
{
var formattedString = new FormattedString();
if (!string.IsNullOrEmpty(LinksText))
{
var splitText = LinksText.Split(' ');
foreach (string textPart in splitText)
{
var span = new Span { Text = $"{textPart} " };
if (IsUrl(textPart)) // a link
{
span.TextColor = Color.DeepSkyBlue;
span.GestureRecognizers.Add(new TapGestureRecognizer
{
Command = _linkTapGesture,
CommandParameter = textPart
});
}
formattedString.Spans.Add(span);
}
}
this.FormattedText = formattedString;
}
private bool IsUrl(string input)
{
return Uri.TryCreate(input, UriKind.Absolute, out var uriResult) &&
(uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
}
private static void OnLinksTextPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var linksLabel = bindable as LinksLabel;
linksLabel.SetFormattedText();
}
}
使用<custom:LinksLabel
LinksText="blah blah blah www.google.com blah"/>
但是同样,这不会将任何内容呈现给超链接。
尝试此解决方案,它将为您提供外观超链接。
XAML:
<Label HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<Label.FormattedText>
<FormattedString>
<Span Text="Hello " />
<Span Text="Click Me!"
TextColor="Blue"
TextDecorations="Underline">
<Span.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ClickCommand}"
CommandParameter="https://xamarin.com" />
</Span.GestureRecognizers>
</Span>
<Span Text=" Some more text." />
</FormattedString>
</Label.FormattedText>
</Label>
如果使用ViewModel create命令或使用轻击手势
public ICommand ClickCommand => new Command<string>((url) =>
{
Device.OpenUri(new System.Uri(url));
});