Monthly Archives: March 2016

So I created this AwesomeHyperLinkLabel custom renderer control one day for Xamarin Forms!

Have you ever wanted to create a Label that could automatically detect HTTP Web Links ? or Phone number text ? or EMail address text ? and enable clickable action only on top of those links in the Label ? 😉

Well it’s a very common scenario in Mobile Apps development, if you had experienced it already, you know its very easy in Native app development. But when it comes to Xamarin Forms, oh well it’s a different story, whereas people almost end up trying to implement a WebView control instead of the Label and complicate the whole situation. lol 😀 (Yes I have been there too) Well XFLabs have a clickable Label control, but who on earth would want to make an entire Label control clickable only for a specific set of text like an email address inside a label, unless your intension is to fill the whole label with the email address only. 😛

Anyhow there was this one time I wanted to create a Label which automatically detect HTTP Web URLs, Phone Number text, Email Address text and enables clickable actions only on top of those specific types of text.

Solution ?

Well if it’s impossible to do it in Xamarin Forms, of course we need to praise the Custom Renderers, just like I did in my scenario. So here goes my solution. We are going to create a Custom Control in Xamarin Forms, which is going to be overridden in native Level and adjust the control to our needs. And I’m gonna call it the “AwesomeHyperLinkLabel

PCL Implementation

So as usual, we create a custom control based on the Xamarin Forms Label as shown below…

namespace WhateverYourNamespace
{
    /// <summary>
    /// Automatically detects the Phone numbers, web links and email addresses
    /// and make them clickable to be opened up in default device applications
    /// </summary>
    public class AwesomeHyperLinkLabel : Label
    {

    }
}

 

Android Implementation

In Android we have the option property in default TextView called AutoLinkMask , which allows us to automatically set the TextView to detect and highlight all kinds of URLs, Phone Numbers, and EMail addresses.

[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);
        }
    }
}

 

So as you can see above I have overridden the Xamarin Forms control with our native TextView control. Make sure to set text after setting the AutoLinkMask, otherwise the link-able text would not be detected by the TextView. Also keep in mind here you could define specifically what types of link-able data you need the Label to detect based on your requirements. 😉 but above example I have set it to all.

iOS Implementation

Also in iOS, we could use DataDetectorTypes property on UITextView which allows us to do the same as above, but keep in mind in Xamarin iOS UILabel is the equivalent of Xamarin Forms Label, but UILabel doesn’t have such properties to support our scenario. So we have to move to the native UITextView control.

It’s very important to keep in mind due to the above reasons we cannot derive this Custom Renderer from the usual LabelRenderer, we need to use the common ViewRenderer.

[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);
        }
    }
}

 

So as you can see above we are setting the DataDetectorTypes property in UITextView to allow the control to highlight the link-able data. Also specially note that we are using ViewRenderer and overriding the Xamarin Forms Label with UITextView control.

That is why we have disabled the Editable property above and we are doing our best for this control to behave as a Label.

Let’s try it out!

Too bored to try it out yourself ? 😛 Yeah thought so. lol Anyways here’s a sample code where you could try out my AwesomeHyperLinkLabel.

public App()
{
	// The root page of your application
	MainPage = new ContentPage
	{
		Content = new StackLayout
		{
			VerticalOptions = LayoutOptions.Center,
			Padding = new Thickness(10, 0, 10, 0),
			Children = {
				new Label
				{
					Text = "Hello! This is normal Label!"
				},
				new AwesomeHyperLinkLabel {
					Text = "Hello! This is the AwesomeHyperLinkLabel by ÇøŋfuzëÐ SøurcëÇødë ! \n\nClick here www.confuzed-sourcecode.com and phone number : +65 9215 7231 and email address : udara.blahblah@blah.com"
				},
			}
		}
	};
}

 

Very well, there you go fellas, now hit F5 and run that thing… 😉

TADAAAA!

WOOT WOOT ! Here how it is in iOS and Android ! 😀

Simulator Screen Shot 8 Mar 2016, 2.09.12 PM Nexus 4 (Lollipop) Screenshot 1

Cheers!

Stay awesome fellas! 🙂

 

Advertisements

How to handle Xamarin Forms WebView internal Navigations!

So you put a Webpage or some HTML content inside your Xamarin Forms WebView ? Specially with Hyperlinks? Or basically you loaded a whole Website inside the WebView?  And now you are worried you can’t control or monitor the Navigation inside the WebView with all those Hyperlink clicks?

Situation…

Oh well I have been in the same situation, where I basically loaded a WebPage and then I wanted to control and monitor it’s internal HyperLink clicks. We already know that the Xamarin Forms WebView doesn’t come with a lot of control properties, but lucky enough they have wrapped the Navigating event of the WebView which could help us Control/Monitor the Hyperlink clicks/navigations inside the Xamarin Forms WebView.

So this is how you do it…

It’s pretty easy actually, but a lot of developers miss this event when it comes to the Xamarin Forms WebView. We can easily subscribe to the Navigating event of the WebView, whereas whenever the user clicks on any HyperLink inside the WebView the action goes through this event, thereby allowing us to monitor and control the hyperlink click of the WebView.

Inside the Navigating Event we have the access to the Event parameter, which let’s us access what the HyperLink that the user clicked on, and as you can see in the below code, I have checked what’s the HyperLink user clicked on and based on that URL string, I’m executing my custom action.

Also keep in mind this allows you to even Cancel that certain HyperLink click event, once you execute your own overridden process as you can see below.

mywebView.Navigating += (s, e) =>
{
	if (e.Url.StartsWith("https://www.whateverlink112312.com.sg/"))
	{
		// now do this instead of navigating within the WebView...
		//....
		//....
		// and finally cancle the defauly WebView Navigation...
		e.Cancel = true;
	}
	else if (e.Url.StartsWith("https://www.whateverlink4444.com.sg/"))
	{
		// now do this instead of navigating within the WebView...
		//....
		//....
		// and finally cancle the defauly WebView Navigation...

		e.Cancel = true;
	}
	else if (e.Url.StartsWith("https://www.whateverlink333333.com.sg/"))
	{
		// now do this instead of navigating within the WebView...
		//....
		//....
		// and finally cancle the defauly WebView Navigation...

		e.Cancel = true;
	}
};

 

So just like that you can gain access to the entire HyperLink click event and control or monitor it in anyways as you wish. For example different actions for different types of HyperLink clicks. 😉

There you go fellas! 😀

Stay Awesome! 😉

Alright, let’s make a Transparent Xamarin Forms Webview!

Have you ever wanted to add a WebView to your Xamarin Forms app and make it’s background transparent ? Let’s say you need to display some custom Text Label’s or some custom control with loads of customization to it’s content or sub controls ?
Whereas your first solution would be to go for a WebView control, but you need to make that WebView Transparent to match the background color of the page ? If you had gone through or going through such requirements, then this article is for you.

WebView for Fancy Stuff…

We all know WebView is usually used for displaying Web Content right ? but then also we could use it to display complicated customized text or content, but then there is one problem, matching the Page background to the WebView control, because it’s impossible to set the background transparent of the WebView in Xamarin Forms.

Solution ?

Yeah you guess right! Custom Renderers for the RESCUE! WOOT!

So here is how I implemented my Transparent WebView with life-saving Custom Renderers in Xamarin Forms.

PCL implementation

So as usual we need to sub-class the default Xamarin Forms WebView control with our Transparent WebView control as follows.

namespace TransparentWebViewXamForms
{
    /// <summary>
    /// Subclassing our Transparent WebView from 
    /// the default Xamarin Forms WebView control
    /// </summary>
    public class TransparentWebView : WebView
    {

    }
}

 

Android implementation

So as of our Android implementation we need to access the native control counterpart for the Xamarin Forms WebView using the WebViewRenderer.

[assembly: ExportRenderer(typeof(TransparentWebView), typeof(TransparentWebViewRenderer))]
namespace TransparentWebViewXF.Droid
{
    public class TransparentWebViewRenderer : WebViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
        {
            base.OnElementChanged(e);

            // Setting the background as transparent
            this.Control.SetBackgroundColor(Android.Graphics.Color.Transparent);
        }
    }
}

 

We access the Control property which holds the native Android WebView control which deals with the Xamarin Forms WebView. As you can see above we set the Control Background color to Transparent through SetBackgroundColor() method. BOOM! You are good to go with Android!

iOS implementation

Now let’s dive into iOS, well its the same as Android, the trick is to set the Control’s background color to Transparent.

[assembly: ExportRenderer(typeof(TransparentWebView), typeof(TransparentWebViewRenderer))]
namespace TransparentWebViewXF.iOS
{
    public class TransparentWebViewRenderer : WebViewRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
			
	    // Setting the background as transparent
            this.Opaque = false;
            this.BackgroundColor = Color.Transparent.ToUIColor();
        }
    }
}

 

But also we need to set the Opaque property to false as show above, otherwise the control wouldn’t render as transparent. Then as usual we set the BackgroundColor property.

So let’s try it out!

Too lazy to try it out ? 😛 No worry, I would probably be bored to try it out unless I actually need to. haha.

So here goes the sample implementation, if you have implemented the above properly, then use the below test code and run your app!

You can see below, I’m setting the Page’s background color to Red and the StackLayout’s background color to Yellow. Now the WebView should be rendered as Transparent and the Yellow background should be visible. 🙂

MainPage = new ContentPage
{
	BackgroundColor = Color.Red,

	Content = new StackLayout
	{
		BackgroundColor = Color.Yellow,
		VerticalOptions = LayoutOptions.CenterAndExpand,
		Children = {
			new Label {
				XAlign = TextAlignment.Center,
				TextColor = Color.Red,
				FontSize = 20,
				Text = "Welcome to Xamarin Forms!"
			},

			new TransparentWebView() { 
				Source = new HtmlWebViewSource()
				{
					Html = @"<html><body>
						<center>
						<h1>Awesome Transparent WebView!</h1>
						<p>by ÇøŋfuzëÐ SøurcëÇødë</p>
						<br> call us : <a href='tel:+6576216231'>1-847-555-5555</a>
						<br> email us : <a href='mailto:webmaster@example.com'>blah@blah.com</a>
						<br> visit us : <a href='http://www.awesome.com'>Awesome.com</a>
						</center>
						</body></html>",
				},
				HeightRequest = 400
			},

			new Label {
				XAlign = TextAlignment.Center,
				TextColor = Color.Red,
				FontSize = 20,
				Text = "And that's the end of it! Have fun!"
			},
		}
	}
};

 

BOOM! THERE YOU GO! 😀

Simulator Screen Shot 2 Mar 2016, 10.23.43 PM Nexus 4 (Lollipop) Screenshot 1

Alright! Now go crazy with it fellas!

Stay Awesome! 😉