Anand
Anand

Reputation: 1959

Xamarin open hyperlink in native webview

I am developing a chat app in xamarin.forms. For my chat label, I used a custom label that could automatically detect HTTP Web Links. The link I followed is HyperLink Label. It works well, the URLs are highlighted and open in the default browser but I'd like to be able to catch the URL click event and open an internal browser or webview instead. Currently, the hyperlink click will open suggestions for choosing the other browser applications. I see this similar question in xamarin.forum. But I didn't understand the solution. So how can I open the hyperlink in the internal browser or webview? Any help is appreciated.

Hyperlink detector label

public class AwesomeHyperLinkLabel : Label
    {

    }

Android Part

[assembly: ExportRenderer(typeof(AwesomeHyperLinkLabel), typeof(AwesomeHyperLinkLabelRenderer))]
namespace WhateverYourNamespace
{
    public class AwesomeHyperLinkLabelRenderer : LabelRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);

            var view = (AwesomeHyperLinkLabel)Element;
            if (view == null) return;

            TextView textView = new TextView(Forms.Context);
            textView.LayoutParameters = new LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent);
            textView.SetTextColor(view.TextColor.ToAndroid());

        // Setting the auto link mask to capture all types of link-able data
            textView.AutoLinkMask = MatchOptions.All;
        // Make sure to set text after setting the mask
            textView.Text = view.Text;
            textView.SetTextSize(ComplexUnitType.Dip, (float)view.FontSize);

        // overriding Xamarin Forms Label and replace with our native control
            SetNativeControl(textView);
        }
    }
}

IOS Part

[assembly: ExportRenderer(typeof(AwesomeHyperLinkLabel), typeof(AwesomeHyperLinkLabelRenderer))]
namespace WhateverYourNamespace
{
    public class AwesomeHyperLinkLabelRenderer : ViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<View> e)
        {
            base.OnElementChanged(e);

            var view = (AwesomeHyperLinkLabel)Element;
            if (view == null) return;

            UITextView uilabelleftside = new UITextView(new CGRect(0, 0, view.Width, view.Height));
            uilabelleftside.Text = view.Text;
            uilabelleftside.Font = UIFont.SystemFontOfSize((float)view.FontSize);
            uilabelleftside.Editable = false;

        // Setting the data detector types mask to capture all types of link-able data
            uilabelleftside.DataDetectorTypes = UIDataDetectorType.All;
            uilabelleftside.BackgroundColor = UIColor.Clear;

        // overriding Xamarin Forms Label and replace with our native control
            SetNativeControl(uilabelleftside);
        }
    }
}

My XAML

<controls:HyperLinkLabel TextColor="White"  Text="www.google.com" HorizontalOptions="Start" />

Upvotes: 0

Views: 681

Answers (1)

Lucas Zhang
Lucas Zhang

Reputation: 18861

If you want to open the web in WebView . You could open a new Content Page when click the label .

await Navigation.PushAsync(new WebContentPage(source));

WebContentPage

<ContentPage.Content>
   <StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
     <WebView Source="{Binding source}" />
   </StackLayout>
</ContentPage.Content>
public HtmlWebViewSource source { get; set; }

public WebContentPage(string Websource)
{
  InitializeComponent();

  source = new HtmlWebViewSource() { BaseUrl=Websource};

  BindingContext = this;
}

Update

        var urlStr = "12122wwwww.google.com";

        int startIndex=0, endIndex=0;

        if(urlStr.Contains("www."))
        {
            startIndex = urlStr.IndexOf("www.");
        }

        if (urlStr.Contains(".com"))
        {
            endIndex = urlStr.IndexOf(".com")+3;
        }

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

            Span span1 = new Span() { Text = urlStr.Substring(0,startIndex) , TextColor = Color.Black,FontSize=20};
           
            formattedString.Spans.Add(span1);

            Span span2 = new Span() { Text = urlStr.Substring(startIndex, endIndex-startIndex+1), TextColor = Color.Blue, FontSize = 20};
            span2.GestureRecognizers.Add(new TapGestureRecognizer() { NumberOfTapsRequired = 1, Command = new Command(() => { }) } );

            formattedString.Spans.Add(span2);

            Span span3 = new Span() { Text = urlStr.Substring(endIndex, urlStr.Length-1-endIndex), TextColor = Color.Black, FontSize = 20};
            formattedString.Spans.Add(span3);

            label.FormattedText = formattedString;
        }

        else
        {
            label.Text = urlStr;
        }

Upvotes: 1

Related Questions