Anand
Anand

Reputation: 1959

Multiple URL Highlight using label span- xamarin.forms

I have a xamarin.forms app which contains a label. The label text sometimes contains URLs. So I am trying to highlight the URL using span and provide a click to it. Currently it will higlight only If my label contains single URL.I done this using assigning three spans manually. But how can implement it for multiple URL detection? Like eg: "Hey check this www.stackoverflow.com and www.forum.xamarin.com".Currently first URL will only highlighted.Any help is appreciated.

What I have done

OnSendCommand = new Command(() =>
            {

                if (!string.IsNullOrEmpty(TextToSend))
                {

                    var urlStr = TextToSend;


                    int startIndex = 0, endIndex = 0;

                    string[] words = urlStr.Split(' ').ToArray();


                    foreach (string str in words)
                    {
                        if (IsUrl(str))
                        {
                            startIndex = urlStr.IndexOf(str);
                            endIndex = str.Length ;
                        }
                    }

                    if (startIndex != 0 || endIndex != 0)
                    {
                        var formattedString = new FormattedString();

                        Span span1 = new Span() { Text = urlStr.Substring(0, startIndex), TextColor = Color.White };

                        formattedString.Spans.Add(span1);

                        Span span2 = new Span() { Text = urlStr.Substring(startIndex, endIndex), TextColor = Color.LightSkyBlue, TextDecorations = TextDecorations.Underline, FontAttributes = FontAttributes.Italic };
                        span2.GestureRecognizers.Add(new TapGestureRecognizer()
                        {
                            NumberOfTapsRequired = 1,
                            Command = new Command(async () => {

                                await PopupNavigation.Instance.PushAsync(new WebViewPopup(span2.Text));
                            })
                        });

                        formattedString.Spans.Add(span2);

                         Span span3 = new Span() { Text = urlStr.Substring(startIndex+endIndex, urlStr.Length - (startIndex + endIndex)), TextColor = Color.White };
                        formattedString.Spans.Add(span3);
                        var message = new Message
                        {
                            Text = formattedString,
                            IsIncoming = false,
                            MessageDateTime = DateTime.Now
                        };
                        Messages.Add(message);
                        TextToSend = string.Empty;
                    }

                    else
                    {
                        var message = new Message
                        {
                            Text = urlStr.ToString(),
                            IsIncoming = false,
                            MessageDateTime = DateTime.Now
                        };
                        Messages.Add(message);
                        TextToSend = string.Empty;
                    }                
                }

            });



         private static bool IsUrl(string url)
        {
            string pattern = @"((https?|ftp|file)\://|www.)[A-Za-z0-9\.\-]+(/[A-Za-z0-9\?\&\=;\+!'\(\)\*\-\._~%]*)*";
            Regex reg = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
            return reg.IsMatch(url);
        }

Upvotes: 0

Views: 266

Answers (1)

Lucas Zhang
Lucas Zhang

Reputation: 18861

You could set the formattedString as global property of the class(ViewModel or ContentPage)

FormattedString formattedString { get; set; }
    if (!string.IsNullOrEmpty(urlStr))
        {

            string[] words = urlStr.Split(' ').ToArray();

            formattedString = new FormattedString();

            foreach (string str in words)
            {
                if (IsUrl(str))
                {
                    Span span = new Span() { Text = str, TextColor = Color.Blue, TextDecorations = TextDecorations.Underline, FontAttributes = FontAttributes.Italic };
                    span.GestureRecognizers.Add(new TapGestureRecognizer()
                    {

                    });

                    formattedString.Spans.Add(span);

                }

                else
                {
                    Span span = new Span() { Text = str, TextColor = Color.Black };

                    formattedString.Spans.Add(span);
                }
            }

            if (formattedString.Spans.Count != 0)
            {
               // label.FormattedText = formattedString;
            }

            else
            {
              //  label.Text = urlStr;
            }

        }

Upvotes: 1

Related Questions