All posts by ÇøŋfuzëÐ SøurcëÇødë

About ÇøŋfuzëÐ SøurcëÇødë

Udara Abhilash Alwis (a.k.a ÇøŋfuzëÐ SøurcëÇødë) Sri Lankan | Geek | Developer | Software Engineer | APIITian | Runner | Cycler |Traveller | Adventurer. Dot net, C#, Java, Xamarin, Windows Phone, Android dev, Inventions, Imaginations, Creativity, and FOSS enthusiast ! ;)

Ze Flippable View in Xamarin.Forms with Native Animations…

Let’s blend some Native Animation goodness to our Flippin’ Flipity Flippable View in Xamarin.Forms…

So I hop yol’ remember my previous post, It’s a Flippin’ Flipity Flippable View in Xamarin.Forms! where I showcased my awesome control built right from Xamarin.Forms without any native code implementation. 😉

  

But you may have noticed a slight issue in the Flip Animation, specially on Android and iOS as well (slightly though), where Flip animation moves the View out of it’s bounds.

^As you can see above, in the animation screenshots… 😮

Some improvement needed…

If you look closely, during the flip rotation, the View sort of scales up itself and moves out of the bounds of itself and scales back and revert back to the normal bounds.

This was kind of annoying me from a personal perspective, so that’s why I thought of finding a solution by trying to render the whole animation natively for Android and iOS separately. 😀

Behold ze Native Animation…

So basically the whole logic of the FlipViewControl is going to be the same, only the animation part would be executed natively. Let’s discuss how we could implement a native animation for each Android and iOS below. 😀

As of Android…

As of Android, the reason why the View scales out of bounds during the flip animation is because that is the default behavior of Flip Animation in Android. Since Xamarin.Forms Aniamtions binds to the native default behavior you could definitely expect it to behave that way. There’s an aspect called Camera View distance perspective for any given view, by default during any animation the Camera View aspect doesn’t change, thus causing the overblown effect of the Flip Animation.

So by implementing a native animation what we could achieve is to control the Camera View Distance value for each animation frame manually, also something to keep in mind this needs to be done according to the Screen density. I found this solution thanks to this forum post:  https://forums.xamarin.com/discussion/49978/changing-default-perspective-after-rotation

As of iOS…

Here for the iOS its not much of an issue, but you do see a bit of the View scaling out of the boundary. So let’s dive into the iOS native flip animation.

We’ll be using a CATransform3D to maintain the transformation of the View’s Layer and execute the animation using UIView.Animate(), we will be using two CATransform3D objects to make sure the View doesn’t scale beyond the boundaries during the animation. This whole awesome solution I found via a random snippet search https://gist.github.com/aloisdeniel/3c8b82ca4babb1d79b29

Time for some coding…

Let’s get started off with the subclassed custom control, naming it XNFlipView and the implementation is actually same as our previous XFFlipView control implementation, but the only difference is there’s no Xamarin.Forms Animation implementation, or handling of the IsFlipped property in the PCL code, since it will be handled in the Renderer level.

public class XNFlipView : ContentView
{
	public XNFlipView()
	{
		...
	}

	public static readonly BindableProperty FrontViewProperty
	...

	public static readonly BindableProperty BackViewProperty
	...
	
	// Everything else is same as XFFlipView implementation

	public static readonly BindableProperty IsFlippedProperty =
	BindableProperty.Create(
		nameof(IsFlipped),
		typeof(bool),
		typeof(XNFlipView),
		false,
		BindingMode.Default,
		null);

	/// <summary>
	/// Gets or Sets whether the view is already flipped
	/// ex : 
	/// </summary>
	public bool IsFlipped
	{
		get { return(bool)this.GetValue(IsFlippedProperty);}
		set { this.SetValue(IsFlippedProperty, value); }
	}
	
	...
}

 

You can take a look at the full class implementation in the github repo file: XFFlipViewControl/XNFlipView.cs

Native Renderers implementation…

Since the animations are going to be handled natively, we need to create the Custom Renderers for our XNFlipView for Android and iOS separately, so let’s get started…

Android Custom Renderer

Alright then let’s go ahead and create the XNFlipViewRenderer  extending from ViewRenderer, as of Xamarin.Forms 2.5 and later we have to pass the Context in the Custom Renderer’s constructor, so let’s begin with that.

public class XNFlipViewRenderer : ViewRenderer
{
	private float _cameraDistance;

	private readonly ObjectAnimator _animateYAxis0To90;
	private readonly ObjectAnimator _animateYAxis90To180;

	public XNFlipViewRenderer(Context context) : base(context)
	{
		...
		//Animation Initialization
		...
	}

	protected override void 
		OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
	{
		base.OnElementChanged(e);

		if (((XNFlipView)e.NewElement) != null)
		{
			// Calculating Camera Distance 
                        //to be used at Animation Runtime
			// https://forums.xamarin.com/discussion/49978/changing-default-perspective-after-rotation
			var distance = 8000;
			_cameraDistance = Context.Resources.DisplayMetrics.Density * distance;
		}
	}

	protected override void 
		OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
	{
		base.OnElementPropertyChanged(sender, e);

		if (e.PropertyName == XNFlipView.IsFlippedProperty.PropertyName)
		{
			if (!((XNFlipView)sender).IsFlipped)
			{
				this.RotationY = 0;
			}

			AnimateFlipHorizontally();
		}
	}

	private void AnimateFlipHorizontally()
	{
		SetCameraDistance(_cameraDistance);

		_animateYAxis0To90.Start();
	}
}

 

Now as you can see above in the constructor we’re initializing the ObjectAnimator objects _animateYAxis0To90 and _animateYAxis90To180 which will be executing the native Flip Animation.

Then in the Renderer’s OnElementChanged we’re calculating the Camera distance value to be used during the Animations execution as we explained before in the concept.

Also you can see how we’re listening to the XNFlipView.IsFlipped value change and executing Animations.

Next let’s take a look into the Animation execution implementation which goes inside the Constructor as you can see in the previous code snippet…

// Initiating the first half of the animation
_animateYAxis0To90 = ObjectAnimator.OfFloat(this, "RotationY", 0.0f, -90f);
_animateYAxis0To90.SetDuration(500);
_animateYAxis0To90.Update += (sender, args) =>
{
	// On every animation Frame we have to update the Camera Distance since Xamarin overrides it somewhere
	SetCameraDistance(_cameraDistance);
};
_animateYAxis0To90.AnimationEnd += (sender, args) =>
{
	if (((XNFlipView)Element).IsFlipped)
	{
		// Change the visible content
		((XNFlipView)Element).FrontView.IsVisible = false;
		((XNFlipView)Element).BackView.IsVisible = true;
	}
	else
	{
		// Change the visible content
		((XNFlipView)Element).BackView.IsVisible = false;
		((XNFlipView)Element).FrontView.IsVisible = true;
	}

	this.RotationY = -270;

	_animateYAxis90To180.Start();
};

// Initiating the second half of the animation
_animateYAxis90To180 = ObjectAnimator.OfFloat(this, "RotationY", -270f, -360f);
_animateYAxis90To180.SetDuration(500);
_animateYAxis90To180.Update += (sender1, args1) =>
{
	// On every animation Frame we have to update the Camera Distance since Xamarin overrides it somewhere
	SetCameraDistance(_cameraDistance);
};

 

As you can see we’re instantiating the animation objects accordingly to the degree angle of the Y Axis they’re suppose to animate the view. Also something very important is that in each animation frame we’re also updating the Camera View Distance, as we discussed earlier this to prevent the View from scaling beyond it’s boundaries. That SetCameraDistance() call takes of it with the previous calculated value. 😉

You can also change the speed of the animation by changing the SetDuration() parameters, which currently I’ve set to 1 second.

You could take a look at the full implementation of the android custom renderer in the github file: XFFlipViewControl.Android/XNFlipViewRenderer.cs

iOS Custom Renderer

Alright then let’s move to the iOS Custom Renderer…

public class XNFlipViewRenderer : ViewRenderer

   protected override void
       OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
   {
       base.OnElementPropertyChanged(sender, e);

       if (e.PropertyName == XNFlipView.IsFlippedProperty.PropertyName)
       {
           if (((XNFlipView)sender).IsFlipped)
           {
             AnimateFlipHorizontally(NativeView, false, 0.5, () =>
             {
                 // Change the visible content
                 ((XNFlipView)sender).FrontView.IsVisible = false;
                 ((XNFlipView)sender).BackView.IsVisible = true;

                 AnimateFlipHorizontally
                           (NativeView, true, 0.5, null);
             });
           }
           else
           {
             AnimateFlipHorizontally(NativeView, false, 0.5, () =>
             {
                 // Change the visible content
                 ((XNFlipView)sender).FrontView.IsVisible = true;
                 ((XNFlipView)sender).BackView.IsVisible = false;

                 AnimateFlipHorizontally
                             (NativeView, true, 0.5, null);
             });
           }
       }
   }
   
   public void AnimateFlipHorizontally(...)
   {
       ...
   }

 

So here in iOS Renderer, it seems a bit straight forward as we’re simply listening to the IsFlipped property change and directly executing the animation.

Next let’s see the Animation implementation…

//https://gist.github.com/aloisdeniel/3c8b82ca4babb1d79b29
public void AnimateFlipHorizontally
	(UIView view, bool isIn, 
		double duration = 0.3, Action onFinished = null)
{
	var m34 = (nfloat)(-1 * 0.001);

	var minTransform = CATransform3D.Identity;
	minTransform.m34 = m34;
	minTransform = minTransform.
		Rotate((nfloat)((isIn ? 1 : -1) * Math.PI * 0.5),
			(nfloat)0.0f, (nfloat)1.0f, (nfloat)0.0f);
	var maxTransform = CATransform3D.Identity;
	maxTransform.m34 = m34;

	view.Layer.Transform = isIn ? minTransform : maxTransform;
	UIView.Animate(duration, 0, UIViewAnimationOptions.CurveEaseInOut,
		() => {
			view.Layer.AnchorPoint = new CGPoint((nfloat)0.5, (nfloat)0.5f);
			view.Layer.Transform = isIn ? maxTransform : minTransform;
		},
		onFinished
	);
}

 

So that’s basically the animation implementation code, which I have extracted from the given gist link at the top, which I have explained in the concept description as well.

You can change the speed of the flip animation by changing the duration.

You could take a look at the full implementation of the android custom renderer in the github file: XFFlipViewControl.iOS/XNFlipViewRenderer.cs

Try it out eh! 😀

Well its use is exactly same as our previous XFFlipView Control. As of an example you could take a look here in my github file: XNFlipViewDemoPage.xaml

So now to execute the awesome Flip Animation, simply change the value of the IsFlipped as follows.

XNFlipViewControl1.IsFlipped = !XNFlipViewControl1.IsFlipped;

 

As you can see in code behind, we’re changing the value of the control’s IsFlipped property, Simples eh! 😀 This is fully bindable as well, so you can directly bind this to a ViewModel property as well.

...
<xfFlipViewControl:XNFlipView 
     x:Name="XNFlipViewControl1" 
          IsFlipped="{Binding IsViewFlipped}">
...

</xfFlipViewControl:XNFlipView>

 

So you can directly use this in your beautifully crafted MVVM Xamarin.Forms app as well. 😀

Some Live Action…

Here we go baby! iOS and Android running side by side…

 

 

Woot!

Look at that the Flip Animation maintains the Bounds of the View nicely during the animation in both Android and iOS! 😉

This whole awesome project i hosted up in my Github repo : https://github.com/UdaraAlwis/XFFlipViewControl 

Cheers! 😀 Keep on going my fellow devs!

Spread the love…

Advertisements

Me Tech Talking at Xamarin Dev Days 2017, Singapore…

Here’s all about my tech talk at Xamarin Dev Days Singapore 2017, under the session, Cross Platform Native UI with Xamarin.Forms…

So on 4th of November Xamarin Dev Days Singapore 2017, concluded with a massive success, with a full house attendance, and as of me I happened be a presenter there.

a full house turn up at Xamarin Dev Days Singapore 2017…

Hosted by Microsoft with the support of Xamariners and SyncFusion, it was a full day community event.

As of myself, Udara Alwis, I was presenting my tech talk session on Cross Platform Native UI with Xamarin.Forms, where talked all about Xamarin.Forms and building cross platform apps with fully native look and feels, while being able to access platform specific features easily, and the latest updates and features of Xamarin.Forms.

udara alwis presenting tech talk xamarin dev days singapore 2017
oh! that’s me, presenting my tech talk…

Along side with an in detailed Live Demo of how Xamarin.Forms runs natively on Android, iOS and Windows with all the native look and feels.

Here are the event details if anyone’s keep on tito, Xamarin Dev Days event Link: on tito. Also if anyone’s looking for the Event photos, its all hosted in the Xamariners Facebook page and Meetup event page: on Meetup 

So I’m about to share some of the stuff I presented at my talk there, although I will not be diving into every single detail I talked about there, only be focusing on the key points.

Cross Platform Native UI with Xamarin.Forms…

So as we all aware, Xamarin.Forms is all about allowing developers to build native UIs for Android, iOS and Windows from single shared C# code base, while maintaining full native look and feels as well as native features.

In the beginning we had native Xamarin, which is the C# and dot net wrapper around the native platforms, where you had to manually develop the UI layer for each specific platform, but still allowing the shared business logic.

Then came Xamarin.Forms, the new abstraction layer that sits on top of the native platforms and abstracts up all the common properties and behaviors to a single abstraction layer, allowing you to develop the UI in one single code base and deploy directly into native platforms, along with the shared business logic. 😉

Windows vs Xamarin.Forms Development…

Here I did something pretty special that is to compare the UI Controls in Windows Dev Environment, and Xamarin.Forms Dev Environment. This helped most of developers who comes from Windows Development background to easily familiarize themselves for Xamarin.Forms development.

As of the MVVM Architect savvy fellas, do not worry Xamarin.Forms supports full binding out of the box, just like you had in Windows Development.

Eco System and Community…

It had been an incredible rise of the community around Xamarin since the Open-Source initiation by Microsoft, with some incredible statistics. 😮

Some of the Latest and Greatest in Xamarin.Forms…

In this section I dived into some of the latest updates of Xamarin.Forms.

Native View Declarations..

Now you can declare Platform Specific Elements inside your Xamarin.Forms pages, yes that’s correct even from XAML directly. 😀

Page Embedding…

Page Embedding has been one of my favorites, being able to embed Xamarin.Forms Elements in your Xamarin Native code. A great way to adopt Xamarin.Forms elements into your existing Xamarin Native applications. 😉

New Performance Updates…

Yes the Engineers in Xamarin has been busy with improving the performance of Xamarin.Forms lately, which is pretty impressive…

Layout Compression…

So whenever you create user interface in your mobile app, it forms some kind of a hierarchy of the Layouts and Control Elements. And you know for a fact the more higher the hierarchy the more performance is consumed by the Layout Renderer.
So its the same case here in Xamarin Forms, specially here it adds some extra layers in between the UI elements to do its Native Magic.

As you can see above the Xamarin.Forms Layout has 12 Elements in the UI, but in reality at run time it increases up to 19 Elements in the UI.

That’s why they’re introducing this new performance enhancement feature called Layout Compression. So what this new feature does it is remove the unnecessary nesting of the hierarchy and compress it as much as possible.

There you can see above as a result of the new feature how the Layout Hierarchy is flatted and compressed down to 16 Elements.

Fast Renderers…

Yes that literally means speeding up the Rendering process of a given Element at runtime. As we know in Xamarin.Forms, each UI Element has a Renderer attached to it, that handles all the native mapping with Xamarin.Forms layer. This Renderer layer also contributes to the unnecessary UI hierarchy for the Layout Renderer.

That is why with this new Fast Renderers feature they’re merging the Element and its Native Renderer into one single Element, causing the whole UI Layout Hierarchy to compress down itself even further.

As a result you can see above example, the 12 Elements hierarchy we had in Xamarin.Forms has compressed down to 10 Elements at run time, resulting in massive performance improvement.

New Backends…

So Xamarin.Forms is all about Cross Platform application development, that’s why they’re now expanding their horizons into some new platforms, allowing you to write you code in Xamarin.Forms in a single code base and deploy to the new platforms right away, without having to write any native code line at all… 😉

  • Tizen : yaay! Samsung devices…
  • WPF: Oh yeah! beautiful WPF, here we come…
  • GTK#: Ubuntu? or whatever your Linux flavor… 😉
  • MacOS: Woot! Woot! MacOS apps…
More…

And with a lot more awesomeness…

All of it on github…

That’s right, I’ve hosted all of the slideshow and the full demo code up in my github: https://github.com/UdaraAlwis/XamarinDevDays-2017-Singapore-Udara

Finally thanks everyone who attended Xamarin Dev Days Singapore 2017 and contributed to make it a success. 😀

Cheers!

It’s a Flippin’ Flipity Flippable View in Xamarin.Forms!

Something that Flips! Flipity Flippy Flippin’ Flip View right out of Xamarin.Forms yol! 😀

Sometime back while I was trying to push the limits of Xamarin.Forms Views, I came across this requirement of Flipping a View with a cool animation. So let me share the story of it right here as usual…

I wanted to create a control that would have a Front View and a Back View, whilst being able to switch between those two Views in with a cool Flip animation!

Behold ze me effortz… 😀

 

TADAAA! 😀 How cool it is eh! 😉

And its all pure Xamarin.Forms, without a single line of native code… Say whuut! 😀 lol

So yeah let’s see how I did it.

The Golden Recipe…

So the solution here is to simply use a View which can hold two layouts (where we will be placing out child elements in) on top of each other, and rotate the View with the easy use of  Xamarin.Forms Animations, whitest swapping the two layouts on top of each other accordingly.

Ok so let me elaborate step by step.

  • Prepare a MainLayout View to hold two child Layouts (FrontView and BackView) in it
  • Add the FrontView and BackView on top of each other inside the MainLayout  View
  • Rotate the MainLayout 90 degrees using Xamarin.Forms Animations API
  • Swap the FrontView and BackView 
  • Then Rotate the MainLayout another 90 degrees
  • And Repeat the same…

That’s it!

The Golden Control…

Alright let’s start of with creating a custom control, which we shall call the golden XFFlipView which would derive from a ContentView. Then myself be using a RelativeLayout as the Parent Layout View of this control,

I’m using bindable FrontViewProperty and BackViewProperty inside the XFFlipView control to hold the reference of the two child Layout Views that we are going to be using as FrontView and BackView of this Flippin’ Flippity Flippy thing! 😀

Additionally we are going to use a bindable boolean, IsFlippedProperty to handle the flipping of this flip view 😉

Well why all the “bindable properties” you might ask? Oh come on, why not silly! So we can monitor the changes of those properties at run time and react accordingly, such as the IsFlipped property, whereas whenever the value changes we shall be activating the Flip View animation functionality.

public class XFFlipView : ContentView
{
	private readonly RelativeLayout _contentHolder;
	
	public XFFlipView()
	{
		_contentHolder = new RelativeLayout();
		Content = _contentHolder;
	}

	public static readonly BindableProperty FrontViewProperty =
	BindableProperty.Create(...);

	public static readonly BindableProperty BackViewProperty =
	BindableProperty.Create(...);

	public static readonly BindableProperty IsFlippedProperty =
	BindableProperty.Create(...);

	private static void IsFlippedPropertyChanged(BindableObject bindable, object oldValue, object newValue)
	{
		if ((bool)newValue)
		{
			((XFFlipView)bindable).FlipFromFrontToBack();
		}
		else
		{
			((XFFlipView)bindable).FlipFromBackToFront();
		}
	}
	
	/// <summary>
	/// Performs the flip
	/// </summary>
	private async void FlipFromFrontToBack()
	{
		...
	}

	/// <summary>
	/// Performs the flip
	/// </summary>
	private async void FlipFromBackToFront()
	{
		...
	}
}

 

There you have it as we just discussed earlier. Ops I may have forgotten about those two methods at the bottom, so those are the methods we are going to use the actual Flip Animation logic, as you can see they’re are being called every time the IsFlipped property is changed.

Oh for them lazy fellas, here grab the full implementation above on my github: XFFlipView.cs

Ze Animationalization…

Alright time for the reveal of the animation thingy, which has been completely done through the easy to use Xamarin.Forms Animations API. Surprise!!?? 😛

...
private async void FlipFromFrontToBack()
{
	await FrontToBackRotate();

	// Change the visible content
	this.FrontView.IsVisible = false;
	this.BackView.IsVisible = true;

	await BackToFrontRotate();
}
...

So basically that’s the implementation of the above said mystery two methods, as you can clearly see, inside there I’m calling another method called FrontToBackRotate() which is the actual method that performs the animation. And right after that we are swapping the Visibility of the FrontView and BackView. Then continue with the rest of animation in BackToFrontRotate() call, just like how we discussed at the beginning.

Let’s see the actual animation implementation, shall we…

#region Animation Stuff

private async Task<bool> FrontToBackRotate()
{
	ViewExtensions.CancelAnimations(this);

	this.RotationY = 360;

	await this.RotateYTo(270, 500, Easing.Linear);

	return true;
}

private async Task<bool> BackToFrontRotate()
{
	ViewExtensions.CancelAnimations(this);

	this.RotationY = 90;

	await this.RotateYTo(0, 500, Easing.Linear);

	return true;
}

#endregion

 

Oh look at that simplicity eh! Thank you Xamarin.Forms animation! 😀 lol

So what happen over there is first we cancel any pending animation and the do initial Y axis rotate property of the parent View and then actually call on the RotateYTo() of Xamarin.Forms Animations, causing it the parent Layout to rotate around the Y Axis with the given value of degrees.

Then when the parent View is flipping from Back To Front View, the same process’s opposite will be executed. 😀 Simples!

Try it out eh! 😀

Since its full on Xamarin.Forms without a single line of native Xamarin code, you could straightaway use this in your XAML or C# code behind anywhere in your PCL.

<xfFlipViewControl:XFFlipView 
        x:Name="XFFlipViewControl1">

    <xfFlipViewControl:XFFlipView.FrontView>
        <Frame
            Margin="10"
            Padding="0"
            BackgroundColor="#0080ff"
            CornerRadius="10"
            HasShadow="True">
            <Grid>
                <Label
                 Grid.Row="0"
                 FontAttributes="Bold"
                 FontSize="Large"
                 HorizontalTextAlignment="Center"
                 Text="this is front view"
                 TextColor="White"
                 VerticalTextAlignment="Center" />
            </Grid>
        </Frame>
    </xfFlipViewControl:XFFlipView.FrontView>

    <xfFlipViewControl:XFFlipView.BackView>
        <Frame
            Margin="10"
            Padding="0"
            BackgroundColor="#ff0080"
            CornerRadius="10"
            HasShadow="True">
            <Grid>
                <Label
                 Grid.Row="0"
                 FontAttributes="Bold"
                 FontSize="Large"
                 HorizontalTextAlignment="Center"
                 Text="this is back view"
                 TextColor="White"
                 VerticalTextAlignment="Center" />
            </Grid>
        </Frame>
    </xfFlipViewControl:XFFlipView.BackView>

</xfFlipViewControl:XFFlipView>

 

Woot! Such simplicity! 😀 So you can see how I have directly used our awesome XFFlipView control right inside XAML and defined the Front and Back Views. Also I have used a Frame View to make it look cooler 😉 lol

So now to execute the awesome Flip Animation, simply change the value of the IsFlipped as follows.

XFFlipViewControl1.IsFlipped = !XFFlipViewControl1.IsFlipped;

 

As you can see in code behind, we’re changing the value of the control’s IsFlipped property, Simples eh! 😀 This is fully bindable as well, so you can directly bind this to a ViewModel property as well.

...
<xfFlipViewControl:XFFlipView 
     x:Name="XFFlipViewControl1" 
          IsFlipped="{Binding IsViewFlipped}">
...

</xfFlipViewControl:XFFlipView>

 

So you can directly use this in your beautifully crafted MVVM Xamarin.Forms app as well. 😀

Some Live Action…

Here we go baby! iOS and Android running side by side…

  

Oh hold on… there’s more coolness… 😀

 

Ohhh! Eye Candy! 😀

And the craziest thing about it is that, all of this awesomeness is right from Xamarin.Forms, without a single line of native Xamarin code. 😉

Woot!

This whole awesome project i hosted up in my Github repo : https://github.com/UdaraAlwis/XFFlipViewControl 

Oh BTW, you might ask me why on Android during the Animation, the view seem to be expanding out of the view? Yes its basically how the Android native flip animation executes, since Xamarin.Forms directly maps its Animation rendering calls down to native level. But we could easily tweak it up by implementing our own native renderer for the Animation, which we will be looking into in the next post. 🙂

Cheers! 😀 Keep on going my fellow devs!

Spread the love…

I’m building an Atom Simulation with SkiaSharp and Xamarin.Forms!

So lately I’ve been on quite a bunch of adventures with SkiaSharp in Xamarin.Forms! 😀 You know how it is for me, pushing the limits of the framework as usual for the fun 😉 And this right here is one of those adventures I’m going to share with you all…

Little Backstory…

I’ve always been fascinated by the Atom’s graphical structure being the science nerd back in school days. I’ve always loved the simulation of the Electrons circulating around the atom’s core filled with Neutrons and Protons. 😀 So while reminiscing those memories, I was thinking of ways to play around with SkiaSharp framework, and suddenly, AHA! A light bulb lit-up on my head! 😀

I’ve decided to build an Atom Simulation in SkiaSharp, with Xamarin.Forms! 😉

A sneak peek!

  

TADAAA! 😀

So where is it going?

Haven’t you ever thought those animated atom structure simulation they show on TV was very very cool? Well I’m thinking of building a similar simulation with SkiaSharp on top of Xamarin.Forms! 😀

And this is going to be a step by step process, where I shall begin with the basic 2D structure and slowly moving towards the complex animated simulation!

Well I’ve already started developing this some time back, and I’ve made quite a bit of progress.

I have hosted this on Github: github.com/UdaraAlwis/SkiaSharpAtomStructureSo that anyone can try it out or add improvements to it, and yes I’m open for pull requests! 😉

Code behind tech bits?

Well basically as you may have already figured out, it’s a Xamarin.Forms project, and I’m using the awesome SkiaSharp for rendering the graphics.

And to be specific with SkiaSharp I’m using the following to render the cool stuff:

  • 2D Shapes Drawing
  • Canvas Translations and Rotations
  • Continuous Animation Rendering
  • Gradient Shading
  • Touch handling

Pretty cool set of features right there, out of the box with SkiaSharp eh! 😉

Progress so far…

I’ve broken the progressive steps to several Pages in the project for clear distinction between the code behind.

I will be updating this post as the project moves forward with improvements and new progression steps.

And here they are…

1. Atom Silhouette

 

So the first step was to simply build a silhouette of the atom structure. There you have the core with Neutrons and Protons, and the Electrons around it in their own orbits.

Basically I’m using the SkCanvas.DrawCircle() to draw the center core and then SkCanvas.DrawOval() to draw the Oval Orbits around the core. 😉

Then I’m drawing the “Electron dot” for each orbit using the corner most point of the Oval Orbit, which is basically the width of the Oval. Tricky yeah!

You might think how about the angles of the oval? Oh yeah I’m using Canvas Rotation for each orbit draw cycle, SkCanvas.RotateDegrees(xx degrees)! 😀

And there’s a simple +/- increment mechanism for increasing and decreasing the number of electrons around the orbit!

You can take a look at the implementation: AtomSilhouettePage.xaml.cs

2. Atom Orbital Paths

 

Here’s a little improvement for the previous step, where as I’ve added some gradient effect for the drawing of the Oval path with the same SkCanvas.DrawOval() call.

The CreateSweepGradient() is one of the way to create a gradient color effect in SkiaSharp, whereas we’ve used white and dark gray as the color here.

Oh Gradients are always cool yeah! 😉

You can take a look at the implementation: AtomOrbitalPathsPage.xaml.cs

3. Atom Orbital Paths Uneven

 

Now we know in reality the Atom’s electron orbit is not a nice even orbit, so we’re going to reflect just that in this progress step! 😀

So basically I’m randomly generating the Oval’s supposed width for each orbit, thus giving the above output!

You can take a look at the implementation: AtomOrbitalPathsUnevenPage.xaml.cs

4. Atom Animated Silhouette

 

This is the step where I kick it up a notch, with the Animation rendering using SkiaSharp!

So as we all know there’s no direct animation rendering support with SkiaSharp, since its a on demand 2D vector graphics rendering system.

What I’m doing here to get the electron dot’s to movement on the oval orbit, is I’m rendering it’s each 360 degrees positions continuously on a timer loop. Might sound pretty complex, but its actually simple! 😉

You can take a look at the implementation: AtomAnimatedPage.xaml.cs

5. A cool touch feature!

I’ve added something cool for the number of displayed Electron’s incremental mechanism!

 

I’ve added a touch handling feature to the atom’s electron incremental mechanism, so now basically you can swipe up or down the screen to increase or decrease the number of electron orbits of the Atom! 😉 Now instead of clicking on the +/- buttons, rather you could swipe up or down to increase or decrease the electron orbits.

This was done simply using the SkiaSharp’s built in touch event handler, and calculating the touch movement direction, thus determining up or down direction! 😀

6. Atom Animated Uneven Orbits

 

So here’s the next progression step, with uneven orbits animation! I’m using a gradient oval drawing for each orbit, similar to what I’ve explained above in one of the previous steps. And I’m generating the Orbits Width upon a given random value.

You can take a look at the implementation: AtomAnimatedUnevnOrbitsPage.xaml.cs

7. ….T B C…..

This will be the next progression step. Since this post will be a continuously updated post along with every progression step I make in this fun project! 😀 So stay tuned!

 

 

That’s all for now!

So like I said at the beginning, this is a continuous fun protect, which I’ll keep on improving step by step. And once again, I will be accepting your pull requests for any improvements you suggest, or just drop a comment or message me of your suggestions. 😀

Don’t forget, feel free to try this project from my Github repo: github.com/UdaraAlwis/SkiaSharpAtomStructure 

I will be updating this post as the project progresses on hopefully! 😉

Let’s draw basic 2D Shapes with SkiaSharp…

So on my last post I shared a recap of my tech talk on SkiaSharp with Xamarin.Forms, check it out if you missed it: So I gave a Tech Talk on SkiaSharp with Xamarin.Forms…

There I talked about some of the most important parts of the whole 1 hour plus presentation-hands-on-labs session, in which I didn’t share all the details of the whole session. I did a pretty comprehensive demo session there, specially about the 2D drawing basics of SkiaSharp, which I didn’t highlight in that post.

Basic 2D Shapes with SkiaSharp…

So today I thought of sharing the demos I did there, about basic 2D shapes drawing with SkiaSharp more extensively… 🙂 Since there seem to be a lack of tutorials explaining this topic of, “draw basic Shapes with SkiaSharp”, which I think should be more important for beginners!

So buckle up fellas, let’s see how we could draw some of the most commonly used 2D shapes with SkiaSharp with ease… 😉

There’s many out of the box support for drawing basic 2D Shapes from SkiaSharp, such as DrawCircle(), DrawRectangle(), DrawLine(), DrawOval() and so on many more.  You could stright away use those methods or you could even go around it and use Paths and Lines drawing methods of SkiaSharp in order to draw them, which is completely up to you.

But SkiaSharp doesn’t have methods for drawing for every single kind of Geometrical shape there is out there. So if you want to draw some kind of complex shape, then you could basically use a combination of Paths and Lines drawing methods in SkiaSharp, which has many kinds of methods you could come up with. 😉 that’s the beauty of SkiaSharp! Anyways the choice of drawing methods are totally up to you!

Now if you want to get ahead of yourself, you may grab the live hands on demo code I did at the presentation which includes all of the below code, right from my github repo: https://github.com/UdaraAlwis/XFSkiaSharpDemo

Just on a note, here I will not be discussing basics of SkiaSharp or the setting up of SkiaSharp library or the Canvas properties and behaviours, I’ll directly get into the programming of the shapes drawing, but if you want to get a head start, head off to Xamarin SkiaSharp Documentation or my previous post, So I gave a Tech Talk on SkiaSharp with Xamarin.Forms…

1. Simple Stroke Line…

private void SkCanvasView_OnPaintSurface
		(object sender, SKPaintSurfaceEventArgs e)
{
	...
	
	// Drawing Stroke
	using (SKPaint skPaint = new SKPaint())
	{
		skPaint.Style = SKPaintStyle.Stroke;
		skPaint.IsAntialias = true;
		skPaint.Color = SKColors.Red;
		skPaint.StrokeWidth = 10;
		skPaint.StrokeCap = SKStrokeCap.Round;

		skCanvas.DrawLine(-50, -50, 50, 50, skPaint);
	}
}

 

We use the DrawLine() and pass in the Line’s starting point’s XY position and and ending point’s XY position, while passing in the paint configuration, SKPaint as we wish.

 

Since SkiaSharp support pure Xamarin.Forms you can straight away run all your native projects without any hassle of handling native code.

2. Drawing a Circle (Filled)

// Drawing a Circle
using (SKPaint skPaint = new SKPaint())
{
	skPaint.Style = SKPaintStyle.Fill;
	skPaint.IsAntialias = true;
	skPaint.Color = SKColors.Blue;
	skPaint.StrokeWidth = 10;

	skCanvas.DrawCircle(0, 0, 70, skPaint);
}

 

We shall be using the DrawCircle() whilst passing in the Circle’s center XY position and desired radius for it. To define whether its a Filled or Non-Filled circle we’ll be using Style property in our SKPaint configuration.

 

Next let’s draw a Circle with just the stroke (with filling the inner of the circle).

3. Drawing a Circle (Un-filled)

We do this by setting the Style property to Stroke! and everything else is the same 🙂

// Drawing a Circle Stroke
using (SKPaint skPaint = new SKPaint())
{
	skPaint.Style = SKPaintStyle.Stroke;
	skPaint.IsAntialias = true;
	skPaint.Color = SKColors.Red;
	skPaint.StrokeWidth = 10;

	skCanvas.DrawCircle(0, 0, 70, skPaint);
}

 

 

Look how simple eh 😉

4. A Square Rectangle!

How about a standard Rectangle? We shall use the SKRect object to configure our Rectangle as we wish and draw it up!

// Draw Rectangle
SKPaint skPaint = new SKPaint()
{
	Style = SKPaintStyle.Stroke,
	Color = SKColors.DeepPink,
	StrokeWidth = 10,
	IsAntialias = true,
};

SKRect skRectangle = new SKRect();
skRectangle.Size = new SKSize(100, 100);
skRectangle.Location = new SKPoint(-100f / 2, -100f / 2);

skCanvas.DrawRect(skRectangle, skPaint);

 

See it in action? 😉

 

The square root of 69 is 8 something, right? – Drake 😉 lol

5. Let’s draw an Ellipse…

There’s many ways to draw an Eclipse, but most common way is to use DrawOval(), as well as other kinds of complex drawings.

// Draw Ellipse
SKPaint skPaint = new SKPaint()
{
	Style = SKPaintStyle.Stroke,
	Color = SKColors.OrangeRed,
	StrokeWidth = 10,
	IsAntialias = true,
};

SKRect skRectangle = new SKRect();
skRectangle.Size = new SKSize(150, 100);
skRectangle.Location = new SKPoint(-100f / 2, -100f / 2);

skCanvas.DrawOval(skRectangle, skPaint);

 

 

So here we’re configuring a Rectangle with SKRect, which an Ellipse could be mathematically consist of.

6. How about an Arc shape?

Well it’s basically the same concept as of an Ellipse, but since we need an “Arc”, we’re going to use some basic mathematical angles to configure the starting angle, startAngle and sweep angle, sweepAngle of the Arc we’re going to draw with a Path object.

// Draw Arc
SKPaint skPaint = new SKPaint()
{
	Style = SKPaintStyle.Stroke,
	Color = SKColors.BlueViolet,
	StrokeWidth = 10,
	IsAntialias = true,
};

SKRect skRectangle = new SKRect();
skRectangle.Size = new SKSize(150, 150);
skRectangle.Location = new SKPoint(-150f / 2, -150f / 2);

float startAngle = -90;
float sweepAngle = 230; // (75 / 100) * 360

SKPath skPath = new SKPath();
skPath.AddArc(skRectangle, startAngle, sweepAngle);

skCanvas.DrawPath(skPath, skPaint);

 

So there we’re configuring our Path object to start off from -90 degrees and ends up at 230 degrees from the start point, drawing the Arc shape. Notice the comment I’ve added there, showcasing how you could also calculate the Arc’s drawing angle as a percentage value. 😀

 

Pretty cool eh! 😉

7. Did we forget Text?

Did you know you could even draw text on a SkiaSharp canvas right away by using DrawText() method.

// Drawing Text
using (SKPaint skPaint = new SKPaint())
{
	skPaint.Style = SKPaintStyle.Fill;
	skPaint.IsAntialias = true;
	skPaint.Color = SKColors.DarkSlateBlue;
	skPaint.TextAlign = SKTextAlign.Center;
	skPaint.TextSize = 20;

	skCanvas.DrawText("Hello World!", 0, 0, skPaint);
}

 

SkPaint object holds several properties for drawing Text on the canvas, such as TextAlright, TextSize and many more you could play around with..

 

Hello World, indeed! 😉

8. Let’ draw a simple Triangle?

Well SkiaSharp doesn’t have a out of the box method call for drawing a Triangle, this is where simple Drawing path and points comes into play.

So basically what we do is, we’ll draw three lines that’s interconnects at the ending points, using DrawPoints() method and pass in the list of Points that’ll draw the Lines…

// Draw Rectangle
SKPaint skPaint = new SKPaint()
{
	Style = SKPaintStyle.Stroke,
	Color = SKColors.DeepSkyBlue,
	StrokeWidth = 10,
	IsAntialias = true,
	StrokeCap = SKStrokeCap.Round
};

SKPoint[] skPointsList = new SKPoint[]
{
	// Path 1
	new SKPoint(+50,0),
	new SKPoint(0,-70),

	// path 2
	new SKPoint(0,-70),
	new SKPoint(-50,0),

	// path 3
	new SKPoint(-50,0),
	new SKPoint(+50,0),
};

skCanvas.DrawPoints(SKPointMode.Lines, skPointsList, skPaint);

 

See it first may be?

 

So now if you think about it, you could actually draw any kind of a Shape with interconnecting Points and Paths using the above method. 😀

9. Draw any Shape?

It’s true earlier step, in Triangle drawing I said you could use the DrawPoints() and a bunch of Points to draw any kind of shape in SkiaSharp. This is actually a painful, but there’s actually a better way… 😉 yaay!

So basically if you needed to draw any kind of shape, all you need is a Path and a bunch of Points that interconnects. A much easier way to do this is by using a SKPath configuration object, using this you could pass define the Starting Point of the drawing path, move around the drawing path with interconnecting Points by using MoveTo() and LineTo() calls. For this you use the mighty DrawPath() method, which you could use to draw anything on the canvas. 😀

// Draw any kind of Shape
SKPaint strokePaint = new SKPaint
{
	Style = SKPaintStyle.Stroke,
	Color = SKColors.Black,
	StrokeWidth = 10,
	IsAntialias = true,
};

// Create the path
SKPath path = new SKPath();

// Define the drawing path points
path.MoveTo(+50, 0); // start point
path.LineTo(+50, -50); // first move to this point
path.LineTo(-30, -80); // move to this point
path.LineTo(-70, 0); // then move to this point
path.LineTo(-10, +90); // then move to this point
path.LineTo(+50, 0); // end point

path.Close(); // make sure path is closed
// draw the path with paint object
skCanvas.DrawPath(path, strokePaint);

 

There you go…

 

So with the use of SKPath, you could draw any kind of 2D shape as you wish… 😀

10. Final shape?

Oh sorry! there ain’t none! 😛 just put up a 10th point for the fun of it! 😉

Well you could grab all of the above code up in my Github repo: https://github.com/UdaraAlwis/XFSkiaSharpDemo That right there is actually the live hands on demo code I did at my original presentation…

So now get out of here and start drawing 2D with SkiaSharp! 😀

or may be check out my talk on SkiaSharp…

Shape the love fellas! 😀

-Udara Alwis.

So I gave a Tech Talk on SkiaSharp with Xamarin.Forms…

A little back story…

Few months back our company was asked to do a graphics application, so we decided to take a look into graphics rendering libraries available for Xamarin.Forms, given the limited time, we thought of going for SkiaSharp over other alternatives, which we had very little knowledge of how to work with.

But to our surprise we managed to build an incredible app with beautiful interactive graphics and animations completely using SkiaSharp with Xamarin.Forms. So I thought of sharing my experience with the fellow dev community. 😀

Opportunity…

So few weeks back (18th June, 2017), I had the opportunity to give a tech talk-hands on demos, at Singapore Mobile .Net Developers  meetup, under the topic “2D Graphics Rendering in Xamarin.Forms with SkiaSharp”!

udara alwis presentation skiasharp xamarin microsoft

So I’m about to share some of the stuff I presented at this meetup, although I will not be diving into every single detail I talked about there, only be focusing on the key points (mostly on the hands on demo bits). If you’re interested in learning SkiaSharp for Xamarin.Forms, go ahead to the the incredible documentation provided by Xamarin: https://developer.xamarin.com/skiasharp/

Here’s the short recap of the presentation I did over there! 😉

2D Graphics Rendering in Xamarin.Forms with SkiaSharp!

So let’s get started off with the Slideshow Presentation…

And you may grab the live hands on demo code I did at the presentation from my github repo: https://github.com/UdaraAlwis/XFSkiaSharpDemo

Now let’s recap…

Behold the incredible 2D Rendering Engine for Xamarin and Xamarin.Forms, SkiaSharp!

An open source project originally developed by Google(Thank you <3), from C++ language, by the name Skia. It is used across a huge variety of Google’s products, including web graphics rendering and so on. This is a Immediate mode 2D vector graphics rendering system, this framework allows you to do 2D graphics, handling and manipulating image resources and text and a lot of cool stuff. 😀

So SkiaSharp is the C# and DotNet wrapper of Skia framework allowing us to use it right on top of Xamarin, a mono based open source project, where you could add your own contribution to it via: github.com/mono/SkiaSharp!

SkiaSharp for Xamarin.Forms comes with the SKCanvasView that inherits from Xamarin.Forms.View which allows you to use it as just another View in your PCL code, and you don’t have to handle any native implementation, everything is accomplished right in your PCL code. 😉

SkiaSharp basics Demo..

For setting up SkiaSharp, open your nuget manager and install “SkiaSharp.Views.Forms” across your Xamarin.Forms solution, including PCL and platform specific projects.

Add the SKCanvasView to your page as you wish.

<ContentPage
    x:Class="XFSkiaSharpDemo.MainPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:forms="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
    xmlns:local="clr-namespace:XFSkiaSharpDemo">

    <forms:SKCanvasView x:Name="SkCanvasView" PaintSurface="SkCanvasView_OnPaintSurface" />

</ContentPage>

 

Notice the PaintSurface event, the most important execution point you need to handle in order to render your graphics on the SKCanvas. Every time you need to do any kind of a drawing or rendering of 2D graphics on your Canvas, you need to do it in this event, this method is first invoked when the Page appears on the screen, and then if the orientation changes or you could even manually invoke it by calling InvalidateSurface() of your SkCanvasView.

Let’s do that…

public partial class
	MainPage : ContentPage
{
	...

	private void SkCanvasView_OnPaintSurface
		(object sender, SKPaintSurfaceEventArgs e)
	{
		// Init skcanvas
		SKImageInfo skImageInfo = e.Info;
		SKSurface skSurface = e.Surface;
		SKCanvas skCanvas = skSurface.Canvas;

		// clear the canvas surface
		skCanvas.Clear(SKColors.SkyBlue);

		// retrieve the canvas info
		var skCanvasWidth = skImageInfo.Width;
		var skCanvasheight = skImageInfo.Height;
	}
}

 

This event provides you with all the required properties and values to execute your 2D rendering, such as the SKCanvas instance, which is the actual canvas you’re going to do the 2D drawing on, SKImageInfo instance which provides you with details such as actual Width and Height by pixels and so on.

The Clear() method call, clears up the canvas surface and prepare it for rendering new content, by passing it a SKColor object, you can paint it with that color.

2D Graphics with SkiaSharp..

The SKCanvasView is actually a placeholder for the SKCanvas which you can access in the PainSurface() event.

There’s many ways to draw or render stuff on our Canvas, but SkiaSharp also provides us predefined methods that allows us to draw simple types of shapes such as Circles, Lines and Texts, etc.

So usually when you are to do some complex drawings you would be using a combination of all those drawing methods at a given rendering cycle.

Transform Operations…

SkiaSharp allows you to do all kinds of Translations, Scaling, Rotating and even Skewing on the Canvas.

Usually on the Canvas, the X,Y coordinate system starts from the top left most corner and Y axis increments vertically and X axis increments horizontally.

So lets see how we could manipulate this in our favor and do some basic Translation and Scaling on the Canvas.

private void SkCanvasView_OnPaintSurface
	(object sender, SKPaintSurfaceEventArgs e)
{
	...
	
	// move canvas's X,Y to center of screen
	skCanvas.Translate((float)skCanvasWidth / 2,
				(float)skCanvasheight / 2);

	// set the pixel scale of the canvas
	skCanvas.Scale(skCanvasWidth / 200f);
}

 

There we are Translating the Canvas’s X,Y coordinate system to be started off of the center of the screen, and then Scaling the Canvas to the ratio of 200 pixels according to the actual canvas Width.

SKPaint object..

SKPaint object is one of the most important element in SkiaSharp, it holds the configuration for any given type of 2D rendering, so you’ll be storing your drawing configuration in that object, such as Color, Style, Stroke Width/Height, Anti Alias and so on.

SKPaint skPaint = new SKPaint()
{
	Style = SKPaintStyle.Fill,
	IsAntialias = true,
	Color = SKColors.Blue,
};

 

There’s how you instantiate a SKPaint object which you’ll using to render your 2D graphics, it’s got all kinds of drawing properties and configurations you can play around with. 🙂

Draw a simple Circle (Filled and Non-Filled)

Let’s get our hands dirty with some actual 2D drawing eh! 😉

// Drawing a Circle
using (SKPaint skPaint = new SKPaint())
{
	skPaint.Style = SKPaintStyle.Fill;
	skPaint.IsAntialias = true;
	skPaint.Color = SKColors.Blue;
	skPaint.StrokeWidth = 10;

	skCanvas.DrawCircle(0, 0, 50, skPaint);
}

...

// Drawing a Circle Stroke
using (SKPaint skPaint = new SKPaint())
{
	skPaint.Style = SKPaintStyle.Stroke;
	skPaint.IsAntialias = true;
	skPaint.Color = SKColors.Red;
	skPaint.StrokeWidth = 10;

	skCanvas.DrawCircle(0, 0, 70, skPaint);
}	

 

We shall be using the DrawCircle() whilst passing in the Circle’s center XY position and desired radius for it. To define whether its a Filled or Non-Filled circle we’ll be using Style property in our SKPaint configuration.

 

Look how simple and beautiful eh 😉

Since SkiaSharp support pure Xamarin.Forms you can straight away run all your native projects without any hassle of handling native code.

To learn more about drawing on the Canvas you can check out the official Documentation: https://developer.xamarin.com/guides/cross-platform/drawing/

Handling User Interactions…

When it comes to most Xamarin.Forms components, they do not have touch handlers, however the SKCanvasView comes default with a Touch event handler, Touch and a boolean property to enable or disable Touch Events, EnableTouchEvents.

You can straightaway use that even and property to handle touch events on the SKCanvas.

<forms:SKCanvasView x:Name="SkCanvasView" 
		EnableTouchEvents="True" 
		Touch="SkCanvasView_Touch"
		PaintSurface="SkCanvasView_OnPaintSurface" />

 

You can subscribe to it and look for the type of touch event and handle it.

private void SkCanvasView_Touch(
object sender, SKTouchEventArgs e)
{
	if (e.ActionType == 
		SkiaSharp.Views.Forms.SKTouchAction.Pressed)
	{
		_lastTouchPoint = e.Location;
		e.Handled = true;
	}

	_lastTouchPoint = e.Location;

	// update the Canvas as you wish
	SkCanvasView.InvalidateSurface();
}

 

As you can see it gives you the Touch point location. You can get a hold of the event and the touch point and you want to do some drawing on the SKCanvasView, then you could call the InvalidateSurface().

private SKPoint _lastTouchPoint = new SKPoint();
private void SkCanvasView_OnPaintSurface
(object sender, SKPaintSurfaceEventArgs e)
{
	...
	
	using (SKPaint paintTouchPoint = new SKPaint())
	{
		paintTouchPoint.Style = SKPaintStyle.Fill;
		paintTouchPoint.Color = SKColors.Red;
		skCanvas.DrawCircle(
			_lastTouchPoint.X,
			_lastTouchPoint.Y,
			50, paintTouchPoint); // 45
	}
}

 

Here it is in action… pretty simple eh! 😉

  

But this touch handler is very primitive, as in if you want to handle multiple concurrent touch points, or special gesture touches, pan, or zoom and so on, then you need to implement a more advanced low level touch handler, something described as here:

https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/effects/touch-tracking/

That way you could simply attach the above TouchEffect just as a normal effect and see the complex touch events in action.

<Grid>
	<skia:SKCanvasView x:Name="SkCanvasView"
		PaintSurface="SkCanvasView_OnPaintSurface" />
		
	<Grid.Effects>
		<tt:TouchEffect Capture="True"
			TouchAction="OnTouchEffectAction" />
	</Grid.Effects>
</Grid>

 

There you go! 😀

Bitmap Image Handling….

Images are pretty crucial when it comes to  2D Graphics, it gives more of added advantage over your design idea.

As of Xamarin.Forms, the conventional the conventional way of loading an image is, either as an Embedded Resource or Platform Specific Resource.

So in SkiaSharp for Xamarin.Forms, provides you SKBitmap or SKImage for handling your image resources. You have few options to load an image, from a data stream, file path and so on.

The most common way in the sense of Xamarin.Forms architecture, you have the option of loading your Images directly from PCL as Embedded Resources, and then convert it to a SKBitmap or SKImage.

string resourceID = "XFSkiaSharpDemo.Resources.xamarinmonkey.png";
Assembly assembly = GetType().GetTypeInfo().Assembly;

SKBitmap skBitmap;

using (Stream stream 
		= assembly.GetManifestResourceStream(resourceID))
using (SKManagedStream skStream
		= new SKManagedStream(stream))
{
	skBitmap = SKBitmap.Decode(skStream);
}

skCanvas.DrawBitmap(skBitmap, 
	SKRect.Create(-50, -50, 100, 100), null);

 

There you have it, we are using the DrawBitmap() method for drawing the image on canvas.

 

But if you have a Xamarin.Forms ImageSource at hand and you need to use in SKCanvas, then you have convert it a Stream object and convert it to SKBitmap, which you could use to manipulate or draw using SkiaSharp on the Canvas. 😉

Image Filters..

Thanks to SkiaSharp you don’t have to manually implement image filters at all, since it packs a pretty cool set of Image Filters out of the box. 😀

Here’s a small sample of a blur image filter implementation…

// built-it blur image Filter
var filter = SKImageFilter.CreateBlur(5, 5);
var skPaint = new SKPaint();
skPaint.ImageFilter = filter;

skCanvas.DrawBitmap(skBitmap, 
	SKRect.Create(-50, -50, 100, 100), null);

 

SKImageFilters is the class that provides the built in filters. 🙂 You attach that object to a SKPaint configuration and draw the Bitmap with it!

 

Keep in mind, there’s a lot more default Image Filters you could play around with! 😉

*drum beat*! 😀

Rendering Animations…

Although Xamarin.Forms packs some pretty decent set of Animations out of the box, we don’t much control over the animation for customization.

But using something like a 2D Rendering Engine, we could create whatever the animation or customization as we wish. SkiaSharp of course is a great option, but that being said, there’s no direct Animation handling available. Because it’s simply a 2D vector rendering engine.

So this means if you want to render some continuous animation with SkiaSharp, you need to handle every single frame of it manually from your code.

So by actual implementation there’s few ways to do this, but the actual underlying idea is to repeatedly render a given set of values on the Canvas, preferably triggered by a continuous timer of sorts.

Stopwatch stopwatch = new Stopwatch();
bool pageIsActive;
float t;
const double cycleTime = 1000; // in milliseconds

private void InitAnimation()
{
	pageIsActive = true;
	stopwatch.Start();

	Device.StartTimer(TimeSpan.FromMilliseconds(33), () =>
	{
		// calculate t for current 
		// tick with regards to cycletime
		t = (float)(stopwatch.Elapsed.TotalMilliseconds
					% cycleTime / cycleTime);
		// invoke redraw on canvas
		SkCanvasView.InvalidateSurface();

		if (!pageIsActive)
		{
			stopwatch.Stop();
		}
		return pageIsActive;
	});
}

 

The above shows you you could create a simple continuous pulse generator relative to milliseconds and execute a continuous animation. In simple terms the Timer is running each 33 milliseconds, calculates a value (t) based on the total elapsed milliseconds on the stopwatch, relative to the cycle time (controls the speed of animation) and repeats. Then calls the SKCanvas redraw. Make sure to call this method on PageAppearing() to start the timer and set the pageIsActive = false on PageDisappearing() to the timer stops.

private void SkCanvasView_OnPaintSurface
	(object sender, SKPaintSurfaceEventArgs e)
{
	... 
	
	// calculate circle radius for this cycle
	float radius = 70 * t;

	// Drawing a Circle Stroke
	using (SKPaint skPaint = new SKPaint())
	{
		skPaint.Style = SKPaintStyle.Stroke;
		skPaint.IsAntialias = true;
		skPaint.Color = SKColors.Red;
		skPaint.StrokeWidth = 10;

		skCanvas.DrawCircle(0, 0, radius, skPaint);
	}
}

 

There as you can see we are drawing the Circle at the given rendering cycle with relative to the generate “t” value at the Timer. So the Circle’s radius will keep on varying from 0 – 70, thus creating the animation effect.

 

Now keep in mind there’s nothing to worry about the rendering performance, since SkaiSharp is a rendering engine. 🙂 You can configure the animation even more faster as you wish, it wouldn’t make much effect on app’s performance! 😉

More Awesome Stuff…

If you want to learn more, check out Xamarin official documentation: https://developer.xamarin.com/guides/skiasharp/

If you need to check out sample code and demos : https://developer.xamarin.com/SkiaSharpFormsDemos/

This presentation’s demo on github…

That’s right, you can get the full demo code I’ve showcased in the presentation up in my github: https://github.com/UdaraAlwis/XFSkiaSharpDemo

I haven’t shared all the demo code I’ve presented in this blog post, but you call find all of the demo code from my git repo above! 🙂

Conclusion…

Yep that’s pretty much it, just get out of here and build something awesome with SkiaSharp! 😉

Share the love! 😀

Cheers!
– Udara Alwis

A MVVM-styled Service for my Await-able Custom Input Dialogs (XFCustomInputAlertDialog)

So a lot of folks asked me regarding my previous post, An Await-able Transparent, Custom, Popup Input Dialog in Xamarin.Forms! 😉 how they could implement this awesomeness in a MVVM-friendly manner in Xamarin.Forms, instead of having to deal with dirty code-behind ugliness.

Frankly I did the above original implementation in a MVVM-manner, given myself being a MVVM-practitioner, but since there are a lot of newbie Xamarin devs out there, I thought it would help if I push it out there in the simplest manner for the newbies to understand without a hassle.

Anyhow in order to do some justice for the Xamarin-Forms-MVVM practitioners out there, including myself 😉 here I am pushing out how to implement the same awesomeness in Xamarin-Forms MVVM environment in a beautiful code manner! 😀 ❤

Service FTW!

When it comes to dealing with MVVM environments, Services are crucial, which is what we’re going to leverage our previous implementation to.

So we could call up this service from anywhere across our shared code.

This demonstration…

We shall be using Prism as the MVVM framework for this demo Xamarin.Forms project because its awesome! 😉

And create a Service implementation for our XFCustomInputAlertDialog, which we’ll be register with the Prism’s default IoC container.

Rest is pure magic! lol 😉

PS: I shall not be spoon feeding from this post about MVVM or how to set up MVVM framework in Xamarin.Forms, I shall assume you have solid knowledge on MVVM based Xamarin.Forms implementations. 🙂

If you want to be ahead of all, you can grab the Github code from here: https://github.com/UdaraAlwis/XFInputAlertDialogService

Yep this time I’ve created a separate repo for the project. Alright then let’s get started!

Let’s do it…

Taking a step by step approach…

1. Prism MVVM Setup

Add Prism for Xamarin.Forms to your project and do the primarily set up for Prism MVVM framework. (if you’re unaware of how to do this, there’s plenty of tutorials and blog posts online about setting up Prism for Xamarin.Forms)

This also means you’re to set up the Views and ViewModels for the Project. (ex: MainPage -> MainPageViewModel).

2. Set up XFCustomInputAlertDialog basics

There’s few basic things you need to set up from my previous post as follows, and you can go back take a look at that post for these steps,  An Await-able Transparent, Custom, Popup Input Dialog in Xamarin.Forms! 😉

  • Setting up Rg.Plugins.Popup library
  • Create InputAlertDialogBase control
  • Create your Custom Input Views as you wish
  • Manage code-behind of your Custom Input Views

That’s it! nothing more! Alright let’s get started off with leveraging to MVVM!

3. Creating the Service…

So we shall create the service for our Custom Alert Dialogs. We shall call it InputAlertDialogService, thereby start off by creating the interface, IInputAlertDialogService with required methods.

namespace XFInputAlertDialogService.Interfaces
{
    public interface IInputAlertDialogService
    { 
        /// <summary>
        /// Open Text Input Alert Dialog
        /// </summary>
        /// <param name="titleText"></param>
        /// <param name="placeHolderText"></param>
        /// <param name="closeButtonText"></param>
        /// <param name="validationLabelText"></param>
        /// <returns></returns>
        Task<string> OpenTextInputAlertDialog(
            string titleText, string placeHolderText,
            string closeButtonText, string validationLabelText);
			
	
	//add other types of dialog open methods from here..
	// Task<string> OpenCancellableTextInputAlertDialog(...)
	// Task<string> OpenSelectableInputAlertDialog(...)
	// ...
	// ...
    }
}

 

You can add any amount of Service method calls to the interface which you can use to implement the concrete implementation.

github.com/XFInputAlertDialogService/…/Interfaces/IInputAlertDialogService.cs

Next let’s create the concrete implementation of our service, InputAlertDialogService.

namespace XFInputAlertDialogService.Services
{
    public class InputAlertDialogService : IInputAlertDialogService
    {
        public async Task<string> OpenTextInputAlertDialog(
            string titleText, string placeHolderText,
            string closeButtonText, string validationLabelText)
        {
            // create the TextInputView
            var inputView = 
               new TextInputView(titleText, placeHolderText,
                   closeButtonText, validationLabelText);

            // create the Transparent Popup Page
            // of type string since we need a string return
            var popup = new InputAlertDialogBase<string>(inputView);

            // Add the rest of Popup 
	    // Dialog display code below...
	    // just as in XFCustomInputAlertDialog
	    // ...
        }

        //add other types of dialog open methods from here..
        // ...
    }
}

 

There we are inheriting from our interface and doing the necessary concrete implementation. You will add the Popup Dialog instantiating and pushing to the navigation stack logic as you did in XFCustomInputAlertDialog code. Since its going to be repeated I’m not going to post the same code snippet here.

You can take a quick peak in the Gitub Repo though 😉

github.com/XFInputAlertDialogService/…/Services/InputAlertDialogService.cs

Then we need to register our Service Interface and Concrete implementation in the Prism’s default Unity Container.

namespace XFInputAlertDialogService
{
	public partial class App : PrismApplication
	{
		public App
		(IPlatformInitializer initializer = null) :
		base(initializer) { }

		protected override void RegisterTypes()
		{
			...
			
			// services registration
		    Container.RegisterType<IInputAlertDialogService,
			InputAlertDialogService>();
		}
		
		...
	}
}

 

There you go, the service layer is now ready! 😀

4. Consuming the Service…

Now let’s consume our Custom Popup Dialog Service in the ViewModel. First let’s inject it to the ViewModel and prepare it to be used when you need it.

public class MainPageViewModel 
	: BindableBase, INavigationAware
{
	private readonly 
	IInputAlertDialogService _inputAlertDialogService;
	
	public MainPageViewModel(
	IInputAlertDialogService inputAlertDialogService)
	{
		...
	
		_inputAlertDialogService = inputAlertDialogService;
		
		...
	}

        ...
}

 

Thanks to the IoC pattern, look at that beautiful and clean code. 😉

Now you’re ready to invoke the awesome custom popup dialogs from anywhere in your ViewModel. Let’s do that as the final step, shall we?

var result = await 
	_inputAlertDialogService.OpenTextInputAlertDialog(
	"What's your name?",
	"enter here...", 
	"Ok",
	"Ops! Can't leave this empty!");

 

If you don’t get the hint, you can simply create a Command in your ViewModel and bind that to a Button or something in your View and add the above call to the Command’s execution method as shown below. 😉

public DelegateCommand 
		OpenTextInputAlertDialogCommand { get; set; }

public MainPageViewModel(
	IInputAlertDialogService inputAlertDialogService)

{
	...
	
	OpenTextInputAlertDialogCommand = new DelegateCommand(OpenTextInputAlertDialog);
	
	...
}

private async void OpenTextInputAlertDialog()
{
	var result = await 
		_inputAlertDialogService.OpenTextInputAlertDialog(
		"What's your name?",
		"enter here...", 
		"Ok",
		"Ops! Can't leave this empty!");
}

 

There you go pure MVVM-Xamarin.Forms goodness! 😀

If you’re one of the lazy you can grab the whole code from Github: https://github.com/UdaraAlwis/XFInputAlertDialogService

Well fellas, that’s it!

Enjoy! 😀 Share the love!

-Udara Alwis 😀

An Await-able Transparent, Custom, Popup Input Dialog in Xamarin.Forms! ;)

Imagine you wanted to prompt your user with a popup alert dialog (which is also transparent, because its cool! lol) 😉 asking them to enter some value and you want to await the whole task (make it awaitable) while you’re at it, so the execution will halt until the user enter the value, and then retrieve the user entered value to the point of origin? 😀

And just to add some sugar to it, may be you wanted to customize and decorate the appearance of the input view?

Something like this?

Seems pretty cool yeah! That’s what I’m gonna share today!

Right outta Xamarin.Forms?

Now there’s no way you could do either of those things in that scenario right out of Xamarin.Forms! Nope, not with a Modal Popup, which doesn’t support transparency, and not even with DisplayAlerts or ActionSheets, since the’re not customizable, they don’t allow text input or any kind of custom input view, only multiple button selections.

So how could I do it?

Let me explain fellas!

So for transparency and ultimate flexibility of setting up custom popup views, we are going to use the awesome Rg.Plugins.Popup library for Xamarin.Forms and to make the whole Task awaitable let’s use a TaskCompletionSource (Thank you dot net)! 😉

So the trick here for adding custom input views to the popup page, is by creating our Xamarin.Forms custom views using a ContentView and set them to the Content of popup page.

Alright then time for some coding!

Let the coding begin…

But first, setting up!

First thing first create a Xamarin.Forms PCL project in Visual Studio. 🙂

Then install Rg.Plugins.Popup library for Xamarin.Forms through Nuget Package manager.

I’ve actually written a blog post about Rg.Plugins.Popup in my blog right here: So I created a Popup with Transparent background in Xamarin Forms… 😉

Create the Transparent Popup Page…

Once you’re done with that, let’s create our custom Transparent Popup Page using the Rg.Plugins.Popup we just installed.

Something to keep in mind,

  • We should allow it to use Generic data types as for the return data type. 😀
  • Popup page provides us with many cool features, including Page background click handling and back button press handling, which we will override as of disable page background click to dismissal and disable back button press cancellation.
  • Pass in a View and set it to the PopupPage’s Content property, which we will attach the custom input view we want to use in our popup page.
  • Set the transparency level to 0.4 of alpha value.

Let’s call it InputAlertDialogBase.

/// <summary>
/// The awesome Transparent Popup Page
/// sub-classed from Rg.Plugins.Popup
/// Customized for our usecase with
/// Generic data type support for the result
/// </summary>
/// <typeparam name="T"></typeparam>
public class InputAlertDialogBase<T> : PopupPage
{
	public InputAlertDialogBase(View contentBody)
	{
		Content = contentBody;

		this.BackgroundColor = new Color(0, 0, 0, 0.4);
	}

	// Method for animation child in PopupPage
	// Invoced after custom animation end
	protected override Task OnAppearingAnimationEnd()
	{
		return Content.FadeTo(1);
	}

	// Method for animation child in PopupPage
	// Invoked before custom animation begin
	protected override Task OnDisappearingAnimationBegin()
	{
		return Content.FadeTo(1);
	}

	protected override bool OnBackButtonPressed()
	{
		// Prevent back button pressed action on android
		//return base.OnBackButtonPressed();
		return true;
	}

	// Invoced when background is clicked
	protected override bool OnBackgroundClicked()
	{
		// Prevent background clicked action
		//return base.OnBackgroundClicked();
		return false;
	}
}

 

There you go, over to the next step!

Configure the await-able Task properties…

So let’s create a Task and TaskCompletionSource inside our InputAlertDialogBase, to handle await-ability of our “Transparent, Custom, Popup Input Dialog” as I’ve mentioned in the blog title! 😉

public class InputAlertDialogBase<T> : PopupPage
{
	// the awaitable task
	public Task<T> PageClosedTask { get { return PageClosedTaskCompletionSource.Task; } }

	// the task completion source
	public TaskCompletionSource<T> PageClosedTaskCompletionSource { get; set; }

	public InputAlertDialogBase(View contentBody)
	{
		...

		// init the task completion source
		PageClosedTaskCompletionSource = new System.Threading.Tasks.TaskCompletionSource<T>();

		...
	}

	...
}

 

Note that how we are initializing the TaskCompletionSource in the Constructor.

Alright, now our Transparent Popup is ready. Next we need to construct the Custom Input View, that we are going to pass into the InputAlertDialogBase to display and retrieve data input (text or any kind) from the User. 😀

Create your Custom Input View! 😀

Alright this step is totally up to your desires, you could construct any kind of a Custom Input View to be displayed on top of the InputAlertDialogBase we just created above, and retrieve the User’s inputs.

So for this example, let’s create a simple View with Title Label, Text Entry and Ok button yeah! 😉 Also let’s add a simple validation Label inside it to show up if the User tries to leave the Text Entry empty and hit the ok button to quit.

<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
    x:Class="XFCustomInputAlertDialog.InputViews.TextInputView"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <ContentView.Content>
        <StackLayout
            Padding="10"
            BackgroundColor="White"
            HorizontalOptions="CenterAndExpand"
            Spacing="5"
            VerticalOptions="CenterAndExpand">
            <Label
                x:Name="TitleLabel"
                FontSize="Medium"
                Text="Enter the value:" />
            <Label
                x:Name="ValidationLabel"
                FontSize="Micro"
                IsVisible="False"
                Text="You can't leave this field empty!"
                TextColor="Red" />
            <Entry x:Name="InputEntry" Placeholder="Enter Here..." />
            <Button x:Name="CloseButton" Text="Ok">
                <Button.HeightRequest>
                    <OnPlatform x:TypeArguments="x:Double">
                        <On Platform="Android" Value="40" />
                        <On Platform="iOS" Value="30" />
                    </OnPlatform>
                </Button.HeightRequest>
            </Button>
        </StackLayout>
    </ContentView.Content>
</ContentView>

 

As you can see we have created a simple ContentView with a custom Text input view! 😀

Notice that we have explicitly named all the elements and added a button click event, this is to make it easy to set custom textual values to the elements and to handle the OK button’s click event as for the closing of the Popup Page. 🙂

Pretty simple yeah, next let’s handle the back end of this custom View to manage the Textual values, Ok button’s click event and validations.

Let’s manage code-behind of Custom Input View…

Now this is important, if you consider a ContentView, all it’s Child elements are private to it’s class scope, so we can’t observe or interact with any of the property value changes or behaviors from outside of the View.

Therefore we need to create custom properties that will expose those required values and events to the public.

Something to keep in mind here,

  • In order to customize the values displayed in the Child elements of the ContentView (Label,Button, etc..) we should pass in the values to the Constructor and set them to the Child elements there.
  • We should create a public EventHandler to handle the Ok Button’s click event from outside the View and add a public string Propery to expose the text Entry’s value to the public.
  • Subscribe to the Entry’s TextChanged event to reflect the value the public string property.
  • Create a public bindable Boolean property to display or hide Validation label in the ContentView. Or you could handle this internally in the View on the Ok Button’s click event as well, but it would be nice if we could expose the Validations to public so we could handle it outside the View.

public partial class TextInputView : ContentView
{
	// public event handler to expose 
	// the Ok button's click event
	public EventHandler CloseButtonEventHandler { get; set; }

	// public string to expose the 
	// text Entry input's value
	public string TextInputResult { get; set; }

	public TextInputView(string titleText, 
          string placeHolderText, string closeButtonText, 
           string validationLabelText)
	{
		InitializeComponent();

		// update the Element's textual values
		TitleLabel.Text = titleText;
		InputEntry.Placeholder = placeHolderText;
		CloseButton.Text = closeButtonText;
		ValidationLabel.Text = validationLabelText;

		// handling events to expose to public
		CloseButton.Clicked += CloseButton_Clicked;
		InputEntry.TextChanged += InputEntry_TextChanged;
	}

	private void CloseButton_Clicked(object sender, EventArgs e)
	{
		// invoke the event handler if its being subscribed
		CloseButtonEventHandler?.Invoke(this, e);
	}

	private void InputEntry_TextChanged(object sender,
					TextChangedEventArgs e)
	{
		// update the public string value 
		// accordingly to the text Entry's value
		TextInputResult = InputEntry.Text;
	}
}

 

So you can see we are passing in all the required values to set to our Child element’s we are passing in to the Constructor and setting them up there. Also we are subscribing to the Ok Button’s OnClick event and text Entry’s TextChanged event.

Inside the CloseButton_Clicked() event we are invoking the public EventHandler CloseButtonEventHandler if it’s being subscribed to by outside.

As well as  the Entry’s InputEntry_TextChanged() event we are updating the public TextInputResult to reflect the Entry’s text value to the public.

Don’t forget to handle Validations…

Oh and here’s the Bindable Boolean property you should include inside the TextInputView code behind to handle the Validations from outside the View.

public partial class TextInputView : ContentView
{
	...
	
	public static readonly BindableProperty 
           IsValidationLabelVisibleProperty =
		BindableProperty.Create(
			nameof(IsValidationLabelVisible),
			typeof(bool),
			typeof(TextInputView),
			false, BindingMode.OneWay, null,
			(bindable, value, newValue) =>
			{
				if ((bool)newValue)
				{
					  
		((TextInputView)bindable).ValidationLabel
					 .IsVisible = true;
				}
				else
				{
					 
		((TextInputView)bindable).ValidationLabel
					.IsVisible = false;
				}
			});

	/// <summary>
	/// Gets or Sets if the ValidationLabel is visible
	/// </summary>
	public bool IsValidationLabelVisible
	{
		get
		{
			return (bool)GetValue(
                             IsValidationLabelVisibleProperty);
		}
		set
		{
			SetValue(
                         IsValidationLabelVisibleProperty, value);
		}
	}
	
	...
}

 

Now speaking of the bindable IsValidationLabelVisibleProperty, we are updating the Validation Label’s visibility based on its value changes accordingly. 🙂

Following this method, you can create any kind of custom Input Views to be attached to our Transparent Popup Page. 🙂 All you need to do is expose the required Values and Events to the public.

Alright next step…

Time to assemble everything and consume it!

Now we are going to put everything together and get it to be used as our “awaitable Transparent, Custom, Popup Input Dialog”! 😉

Somethings to keep in mind here,

  • We need to initialize our TextInputView by passing in the parameters we would like the necessary child elements to display
  • Create an InputAlertDialogBase<string>(), yes of type string, since we are going to return a string from the Popup Alert.
  •  Subscribe to the CloseButtonEventHandler of TextInputView’s instance to handle validation and reflect the Text input value to the TaskCompletionSource.
  • Push the popup page instance to Navigation Stack and await the page’s Task
  • Upon result retrieval Pop the page from Stack and return the user inserted value.

Alright let’s do it…

private async Task<string> LaunchTextInputPopup()
{
	// create the TextInputView
	var inputView = new TextInputView(
		"What's your name?", "enter here...", 
		"Ok", "Ops! Can't leave this empty!");

	// create the Transparent Popup Page
	// of type string since we need a string return
	var popup = new InputAlertDialogBase<string>(inputView);

	// subscribe to the TextInputView's Button click event
	inputView.CloseButtonEventHandler +=
		(sender, obj) =>
		{
			if (!string.IsNullOrEmpty(
                         ((TextInputView)sender).TextInputResult))
			{
				
                            ((TextInputView)sender)
                               .IsValidationLabelVisible = false;
				
                            // update the page completion source
                            popup.PageClosedTaskCompletionSource
                                .SetResult(
                                ((TextInputView)sender)
                                      .TextInputResult);
			}
			else
			{
				
                             ((TextInputView)sender)
                                 .IsValidationLabelVisible = true;
			}
		};

	// Push the page to Navigation Stack
	await PopupNavigation.PushAsync(popup);

	// await for the user to enter the text input
	var result = await popup.PageClosedTask;

	// Pop the page from Navigation Stack
	await PopupNavigation.PopAsync();

	// return user inserted text value
	return result;
}

 

There you go, step by step as I explained before you can see how it’s being consumed. Specially inside the CloseButtonEventHandler, every time the event fires we are checking the TextInputResult property and enabling or disabling the IsValidationLabelVisible property, as well as updating the PageClosedTaskCompletionSource property value if a text value is being entered by the User, which will in return update the awaiting PageClosedTask and task will proceed to completion state, then return the value after popping the Page. 😀

There you go! 😀 How straight forward is that! 😉

Keep in mind like I said before you can add any kind of a customized View on top of our Transparent Popup Page, and retrieve any kind of result as you expect from the User following the same steps. 😀

Let’s see this in action…

 

Look at that coolness right! 😉

Since it’s full on Xamarin.Forms, and doesn’t have a single line of native code, you could straight up run this implementation on all Android, iOS, UWP, WinPhone as you wish! 😀

I want more! 😮

Alright now that’s just a little bit of basic head start of what you could do, whereas if you get creative and smart you could do a lot more cool stuff like this…

  

 

 

There you have it, some cool stuff I played around with my implementation. 😉

You can grab the Github code from here: github.com/UdaraAlwis/XFCustomInputAlertDialog

Well fellas, that’s it for now!

Enjoy! 😀 Share the love!

-Udara Alwis 😀

Yaay! I became a Xamarin Certified Mobile Developer! :D

So finally on 9th of June 2017, I became a Xamarin Certified Mobile Developer. So here’s my experience of the whole Xamarin University, Certification Exam, and some tips and tricks that might help you! 🙂

Well I’ve been using Xamarin Platform for over 2 and half years now, but I never really thought of getting the official Xamarin Certification until recently my boss encouraged me to and financially supported it.

Down the memory lane of my Mobile Development enthusiasm…

So here’s a little sharing of memories down the memory lane and some tips for getting the Xamarin Certification.

I first started off developing mobile apps on Android platform, given my love for Java programming back in the early days. So I self learned Android App Development back in the middle of 1st year of my college using online tutorials and documentation.

Then at the end of 1st year, I was introduced to Windows Phone App development, which I got completely hooked on it, and then Windows Store App Development and so on, where I ended up publishing over 20+ apps to the Microsoft App Store during the next few years.

Next lucky enough I got a mobile developer opportunity at a medium size local company where it was for Xamarin Mobile Development back in 2014 December. 😀

Learning the whole Xamarin Platform by myself, I ended up completing a full fledged mobile app for that project in that company using Xamarin Forms.

Finally in 2015 December, got an overseas opportunity in Singapore for a Xamarin Mobile Developer position, which is where I ended up mastering the Xamarin Platform, Xamarin Android/iOS native development, hacking to push boundaries of the platform and so on and finally living my dream of being a Mobile App Developer. 😀

And that is where I’m currently working at June 2017, enjoying everyday of it while diving in the goodness of Xamarin Mobile Development. 😉


Xamarin University Training and Certification Preparation…

I was lucky enough my company sponsored me for Xamarin University Subscription. Otherwise its about 1000 USD for 1 year subscription or there a new monthly subscription plan with a very reasonable pricing.

Once you have the subscription you get full access for all the incredible learning materials and live lecture sessions in Xamarin University.

Is it worth it?

Now although at this point I already had like 2 years of Xamarin Mobile developement experience, I must admit that I learned way more and strengthened my knowledge on Xamarin top to bottom thanks to Xamarin University. So if you ask me if it’s worth it? at least for the Knowledge? DEFINITELY YES!

Mandatory Sessions

There’s a mandatory list of sessions that you have to complete before taking the exam, you could completely them either by attending the live lecture sessions or taking self-learn sessions (if available). Yes, some of those mandatory sessions doesn’t have the ‘self-learn’ option yet, so you have to attend to a live lecture session and get your attendance marked for it. 🙂

Instructors?

Mark my words, the instructors in Xamarin University are top-notch, and industry experts with a lot of knowledge and experience, there’s no doubt about them. You can ask anything from them regarding the session, even while the session is going on, they are very helpful and friendly, not to mention their great teaching skills. 🙂

Memorizing vs Understanding!

Do not MEMORIZE! just UNDERSTAND the content! The sessions are structured in a way that it helps you to actually understand the content with step by step exercises. I’ve never taken a single note on any of the sessions, nor tried to memorize stuff(although I’m not very good at it either), just followed through sessions and focused well during them. That’s all it takes!

Anything else?

You can take any live lecture session as many times as you wish, until you feel comfortable with the topic. There’s also many extra sessions you could attend to improve your knowledge in Azure, UI Test, Xamarin Android, Xamarin iOS. It’s good to keep in mind that the exam mandatory sessions are mainly about Xamarin Forms cross platform related topics, so you don’t have to worry if you don’t have much in-depth knowledge about native mobile development. 🙂

They also provide you a Study-Guide check-list to go through to make sure you’re prepared for what’s actually required: https://university.xamarin.com/content/certification#study-guide

Once you’ve completed the mandatory sessions, then you become eligible to sit for the certification exam!


Certification Examination!

So the Certificate Exam is a 3 hours, MCQ exam (Multiple Choice Question) which has 150 questions, and you should score over 80% in order to pass the exam.

The questions scope…

The questions are going to be completely based on the mandatory sessions in Xamarin University. Heavily focused on the Xamarin.Forms cross platform related topics. Personally I did not get any questions that are out of the scope.

So how were the questions…

If you’ve got a solid knowledge on the mandatory sessions, then you have nothing to worry about. Not keep this in mind, about 40% of the questions are straight and easy, but the rest are not going to be hard, but tricky, meaning it’s going to be little bit twisted, so you need to pay good attention to the details in each question before you pick the answer. 😉

Understand the content in the sessions, not memorize!

Basically you won’t be able to make it through the exam if you’re just trying to ‘memorize’ everything in your head, you need to have a ‘good understanding’ of the session content, in order to answer the tricky 60% of the questions.

After the exam?

Once you finish the exam, you get the results immediately. 😉 Then its time to PARRTTAAYYY!!! 😀

Xamarin University and Certification benefits!

First of all the incredible amount of knowledge and experience you gain in the whole process of Xamairn University and the Certification is priceless.

Not to mention the global recognition as Xamarin Certified Mobile Developer, having the official certificate directly validates you as someone who actually knows your way around Xamarin-stuff. Although it does not prove you as an ‘expert’, which is totally dependent on your personal industry experience.

Access to Xamarin DevConnect portal, to showcase your portfolio and connect with fellow developers.

There are few other awesome benefits you get according to Xamarin official site as follows. Certification is valid for 1 year from the date you have passed the exam. Certifications can be verified on our public Xamarin Certified Developers page.

Receive a badge, fun Xamarin swag, and an invitation to join the official Xamarin Certified Developers community on LinkedIn.

Cool, so what do I get to show off?

Except for the massive amount of knowledge and experience I gained from the Xamarin University Sessions and Training, here are some other show-off stuff I got after being certified.

So brace yourselves for some self promotional bragging! 😛

Xamarin Certified Developer Verification Online:

https://university.xamarin.com/certification?q=Udara@xamariners.com#verify

You get a link that can be shared online for the verification of your Certification status. This is the source you could include in your LinkedIn or personal portfolio for the verification.

Xamarin University Profile Badge: 

Once you get the certification, your Xamarin University profile gets updated as such.

Xamarin Certified Developer Certification (soft copy): 

You actually get a PDF version of your certification (here is a screenshot of it).

Bunch of Xamarin Certified Developer badge Images (HD):

Then you get a whole bunch of Certified Mobile Developer badges in low, mid and high resolution for you to share on any of your websites or portfolios. 🙂

Xamarin DevConnect Profile:

You get access to Xamarin DevConnect, the official Xamarin Certified Developer portal from Xamarin, where you can publish your portfolio, connect with fellow certified developers from all over the world, and open up yourself for new opportunities.

https://devconnect.xamarin.com/profile/389


Well that’s it all I got for now… 😀

Although some claim that you get kind of a Xamarin souvenir trophy and a goodie bag by mail, but I’m yet to get any of that. lol. *fingers cross* 😛

So If anyone needs any help or clarifications regarding Xamarin Certification, I’m more than happy to help, drop me a mail or comment down in the post. 🙂

To get started:  https://www.xamarin.com/university

Good luck everyone with your Xamarin Certification! 🙂

Cheers!

Xamarin Forms cross platform architectural implementation patterns…

Let’s talk about how to properly handle advanced cross platform architectural implementations in Xamarin Forms projects, specifically when you’re abstracting native services/implementations in your shared code base, while trying to maintain loosely-coupled and scalable architecture.

Yaay! Xamarin Forms!

Now we all know how Xamarin Forms allows us to build cross platform mobile apps while sharing almost up to 100% of our code base and skill having native performance and look and feels.
It does this by adding a common layer of abstraction which shares properties and behaviors which are common for the native platforms.

BUT…

Despite the incredible architecture of the Framework, one of the main drawbacks of it is that we do not get access to 100% of the native properties and behaviors, thus we only get the “common subset” of behaviors of each native platform that are shareable in a common manner among all the platforms through Xamarin Forms.

OPS…

So when we need to access some properties, behaviors or services that’s not available from Xamarin Forms layer, we need to drill down to the native platform specific level of that certain platform.
Now for UI Controls and their properties or behaviors we could use Custom Renderes or Effects.

But how about inbuilt native Services, such as Storage, Text-to-Speech, Location and so on?

ABSTRACTION FTW!

Turns out it’s all abstraction of an interface and mapping it to a platform specific concrete implementation, which could be described as the famous “Bridge Pattern”.

A BUMMER..

Yes it does seem pretty simple but when it comes to actual practicality of it, then it becomes a little bit complicated or rather messy, unless you follow a proper implementation pattern.
And it only gets more complicated when you keep on scaling your app project.
Therefore it’s very crucial that we maintain a certain set of principal patterns when we do platform specific implementation with abstraction mapping.

THE SOLUTION?

So we need to make sure that we maintain a proper set of principal patterns when deal with this situation as I explained earlier.
Here I’m going to talk about three key principles to deal with advanced cross platform implementations for handling native abstractions.

  • Factory Pattern
  • Service Locator Pattern
  • Dependency Injection Pattern

Now with the above principle patterns you could maintain a properly constructed and easily scalable Xamarin Forms project solution, when you’re dealing with advanced cross platform implementations with abstracting native services. Or rather any kind of an abstraction service implementation you could keep properly maintained by following the above patterns. The key advantage in all the above patterns are decoupled code, and scalability at any given time.

Now keep in mind there’s actually many kinds of patterns you could follow in this scenario or you could come up with your own architectural patterns, but the above are known to be most used among Xamarin Forms projects.

It is best to be aware of them, since you could either use them straight away or modify them according to your requirements. And keep in mind the above principle patterns could become slightly changed from their literal definition when it comes to actual implementation, it’s only the foundation concept that we need to keep in mind when we implement them, and make sure we are following the basics of it at least.

Which one should I use?

There is no such thing as “the best” or “the worse”pattern for cross platform mobile development, it all depends on how you interpret it based on your requirements. The selection of which pattern or architecture suits best for you is totally up to you and your requirements, that is something very crucial to keep in mind. Therefore here in this post I shall be demonstrating each of the above patterns and how to implement them properly in a Xamarin Forms project solution for the same app concept.

Let’s talk Demonstration!

In order to properly demonstrate the above said patterns I will be implementing a simple Xamarin Forms app which allows you to writing notes, save them, view them, read them out loud, edit them, and also delete them. So in that case we will be using native Storage Services and Text-To-Speech Services of those native platforms, while having a shared code base.

Alright now, I’m not going to get into spoon feeding details of how to do each native services implementation such as Storage and Text-To-Speech and implementing the XAML pages for the app and so on, but I will only be focusing on implementing the pattern for the given scenario, which is what matters for this post.

So we are going to create a Xamarin Forms solution in Visual Studio, and keep the interface for the above native services in the PCL or Shared Project (INoteReader and INoteLoader) and have the concrete implementations of them to be moved down to the native projects.

Then to demonstrate the differences of implementation of all the above three patterns I have created a complete solution (XFCPMobilePatterns) which has three sub folders, and included three Xamarin Forms projects in each of them which has the demo for Factory Pattern (XFMyNotesAppFP), Service Locator Pattern (XFMyNotesAppSL) and Dependency Injection w/ IoC (XFMyNotesAppDI).

Yep, that’s how it would look, if you’re interested in diving further into the implementation, You may find the complete solution up on my Github repo: https://github.com/UdaraAlwis/XFCPMobilePatterns

Let’s begin.

1. FACTORY PATTERN with Xamarin Forms

Oh yeah, back to basics yeah? the good old Factory Pattern, which allows you to create objects without exposing the creation logic to the client, or as in without having to aware of the concrete implementation.

So for our implementation we are going to keep a static generic Factory which will handle mapping and creation of the services. And we would request the service by passing the service type.

public static class ServiceLoaderFactory<T>
{
    public static Func<T> CreateService { get; set; }
}

 

Alright next we are going to map our Service Interfaces (INoteReader and INoteLoader) which we have placed in the PCL project, with their actual concrete implementations in the platform specific projects using the ServiceLoaderFactory. Make sure to do this mapping in the run time execution point of each project as shown below.

// Android implementation
protected override void OnCreate(Bundle bundle)
{
	TabLayoutResource = Resource.Layout.Tabbar;
	ToolbarResource = Resource.Layout.Toolbar;

	base.OnCreate(bundle);

	global::Xamarin.Forms.Forms.Init(this, bundle);

	ServiceLoaderFactory<INoteLoader>.CreateService = () => new NoteLoaderDroid();
	ServiceLoaderFactory<INoteReader>.CreateService = () => new NoteReaderDroid();

	LoadApplication(new App());
}

// iOS implementation
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
	global::Xamarin.Forms.Forms.Init();
	LoadApplication(new App());

	ServiceLoaderFactory<INoteLoader>.CreateService = () => new NoteLoaderIos();
	ServiceLoaderFactory<INoteReader>.CreateService = () => new NoteReaderIos();

	return base.FinishedLaunching(app, options);
}

// UWP implementation
public App()
{
	ServiceLoaderFactory<INoteLoader>.CreateService = () => new NoteLoaderUwp();
	ServiceLoaderFactory<INoteReader>.CreateService = () => new NoteReaderUwp();

	this.InitializeComponent();
	this.Suspending += OnSuspending;
}

 

Next we need a NoteManager which is going to keep tract of all the service instances after they’re mapped to their concrete implementations at the run time, and also to maintain sort of a ‘facade-like’ access to the services. So for obvious reasons, we need to make it a singleton access point, as there’s no point of duplicating service objects. Also we are creating the NoteManager to handle basic functions such as loading and saving Notes at run time. 🙂

  public class NoteManager
  {
        // make a singleton access point
        private static readonly NoteManager _instance 
                                          = new NoteManager();
        public static NoteManager Instance 
                                  { get { return _instance; } }


        public IList<MyNote> MyNotes { get; private set; }


        public INoteLoader NoteLoader { get; private set; }
        
        public INoteReader NoteReader { get; private set; }

        private NoteManager()
        {
            NoteLoader = ServiceLoaderFactory<INoteLoader>.CreateService();
            NoteReader = ServiceLoaderFactory<INoteReader>.CreateService();

            MyNotes = new ObservableCollection<MyNote>(NoteLoader.Load());
        }

        public void Save()
        {
            NoteLoader.Save(MyNotes);
        }
  }

 

You can see there in the constructor, how we are loading the Service objects from our ServiceLoaderFactory and mapping them to the public interface instances, so that we could use them anywhere in our app.

Now the reason why I’m maintaining the NoteLoader and NoteReader instances here is because with the Factory Pattern, every time we request a service instance, it creates a new instance of the service and returns to the client, which obviously is not efficient, that’s why I’m retaining those instances in the NoteManager class. But with few tweaks you could easily implement a Factory Pattern which caches instances, and reuse them upon request, but I wouldn’t waste time on that, since we could use Service Locator or Dependency Injection for such scenarios, which I would explain later in the article.

Here’s how to access the above services in anywhere your PCL or Shared Project.

NoteManager.Instance.NoteReader.Speak("Hello, read this!");

 

There you have it, now that shows how to add platform dependent services and use them in your shared code following the Factory Pattern, as you go on scaling up the project solution! 😉

But keep in mind that this may not exactly according to literal definition of “Factory Pattern 101” but rather a customized version of it which I came up with for cross platform implementation, so you might have a different kind of implementation of the same concept, which is totally ‘ok’, as long as the foundation is the same. 🙂

2. SERVICE LOCATOR PATTERN with Xamarin Forms

As we already know, Service Locator Pattern, is all about locating a concrete implementation instance of an abstracted service interfaces at run time.
This is something similar to Factory Pattern, but a different type of a solution for our situation, whereas it maintains a dictionary of registered services which has been mapped with their concrete implementation, which we can look up at run time and retrieve the instance. Now it is considered that Service Locator pattern is a variation of Inversion of Control principle, just as Dependency Injection pattern, which we’ll discuss in the next topic.

This provides an on demand service look up at anywhere in the run time. The native service instances are stored in a dictionary-like data structure inside the Service Locator object, and returned at run time when they’re requested by the interface type. Obviously there will be a singleton static reference to the Service Locator object.

There’s many Service Locator ready-made libraries out there, and heck even Xamarin Forms already provides a solid Service Locator in the framework, which you may have already heard of, Xamarin Dependency Service. So you could use it right out of the box in Xamarin Forms, for your abstracted service implementations.

But that being said it’s not so hard to roll out our own Service Locator (just for the demonstration of it’s mechanics). 😉

So let’s implement our own simple Service Locator, this was actually something I grabbed off of github.

/// <summary>
///     Simple ServiceLocator implementation.
///     Extracted source credit : https://github.com/Azure-Samples/MyDriving/blob/master/src/MobileApps/MyDriving/MyDriving.Utils/ServiceLocator.cs
/// </summary>
public sealed class ServiceLocator
{
	static readonly Lazy<ServiceLocator> instance = new Lazy<ServiceLocator>(() => new ServiceLocator());
	readonly Dictionary<Type, Lazy<object>> registeredServices = new Dictionary<Type, Lazy<object>>();

	/// <summary>
	///     Singleton instance for default service locator
	/// </summary>
	public static ServiceLocator Instance => instance.Value;

	/// <summary>
	///     Add a new contract + service implementation
	/// </summary>
	/// <typeparam name="TContract">Contract type</typeparam>
	/// <typeparam name="TService">Service type</typeparam>
	public void Add<TContract, TService>() where TService : new()
	{
		registeredServices[typeof(TContract)] =
			new Lazy<object>(() => Activator.CreateInstance(typeof(TService)));
	}

	/// <summary>
	///     This resolves a service type and returns the implementation. Note that this
	///     assumes the key used to register the object is of the appropriate type or
	///     this method will throw an InvalidCastException!
	/// </summary>
	/// <typeparam name="T">Type to resolve</typeparam>
	/// <returns>Implementation</returns>
	public T Resolve<T>() where T : class
	{
		Lazy<object> service;
		if (registeredServices.TryGetValue(typeof(T), out service))
		{
			return (T)service.Value;
		}

		return null;
	}
}

 

As you can see how simple and straightforward it is. We maintain a singleton instance of the ServiceLocator, and there are the Add<TContract, TService>() which is used for registering the service interfaces with their concrete implementation and the Resolve<T>() which is used for retrieving the service instance at run time.

Notice how its maintaining a Dictionary of the service instances and retrieve it up on Resolve() call. 😉

Let’s add the above Service Locator to our project and construct it as below. And keep in mind the service implementation is going to be the same, having your service interfaces in the PCL shared project and the concrete implementations in the platform specific projects.

Now with our Service Locator this is how you would register your Service Interfaces (INoteReader and INoteLoader) with their concrete implementations.

// Android implementation
protected override void OnCreate(Bundle bundle)
{
	TabLayoutResource = Resource.Layout.Tabbar;
	ToolbarResource = Resource.Layout.Toolbar;

	base.OnCreate(bundle);

	global::Xamarin.Forms.Forms.Init(this, bundle);
	
	ServiceLocator.Instance.Add<INoteLoader, NoteLoaderDroid>();
	ServiceLocator.Instance.Add<INoteReader, NoteReaderDroid>();
	
	LoadApplication(new App());
}

// iOS implementation
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
	global::Xamarin.Forms.Forms.Init();

	ServiceLocator.Instance.Add<INoteLoader, NoteLoaderIos>();
	ServiceLocator.Instance.Add<INoteReader, NoteReaderIos>();

	LoadApplication(new App());

	return base.FinishedLaunching(app, options);
}

// UWP implementation
public App()
{
	ServiceLocator.Instance.Add<INoteLoader, NoteLoaderUwp>();
	ServiceLocator.Instance.Add<INoteReader, NoteReaderUwp>();

	this.InitializeComponent();
	this.Suspending += OnSuspending;
}

 

Then just like what we had in Factory Pattern implementation we need a NoteManager which is going to handle basic Note managing functions such as loading and saving notes. 🙂

public class NoteManager
{
	// make a singleton access point
	private static readonly NoteManager _instance 
                                          = new NoteManager();
	public static NoteManager Instance 
                                  { get { return _instance; } }


	public IList<MyNote> MyNotes { get; private set; }
	
	private NoteManager()
	{
		var noteLoader = ServiceLocator.Instance.Resolve<INoteLoader>();
		MyNotes = new ObservableCollection<MyNote>(noteLoader.Load());
	}

	public void Save()
	{
		var noteLoader = ServiceLocator.Instance.Resolve<INoteLoader>();
		noteLoader.Save(MyNotes);
	}
}

 

As you can see, compared to the NoteManager we had in the Factory Pattern, this NoteManager is much more simplified and cleaner thanks to the ServiceLocator.

This is because ServiceLocator allows us to maintain a single instance of our services such as INoteLoader and INoteReader, thereby we do not have to worry about duplicating their instances, we could simply access them anywhere in our code.

You can see how its easily calling the ServiceLocator.Resolve<T> to retrieve the service instances. 🙂

Here’s how to access the above services in anywhere your PCL or Shared Project, and notice how we are directly accessing the service instance unlike in Factory Pattern thanks to the ServiceLocator.

ServiceLocator.Instance.Resolve<INoteReader>().Speak("Hello, read this!");

 

There you have it, now this clearly shows how easy it is to add more and more platform dependent services and use them in your shared code as you go on scaling up the project solution, all thanks to Service Locator Pattern! 😉 Altogether while simplifying the shared code compared to the Factory Pattern.

And keep in mind this is a well improved pattern over Factory Pattern, but it still depends on your requirement as to which one is best suited for your implement. 🙂

3. DEPENDENCY INJECTION with Xamarin Forms

Now this right here is like the holy grail or the most praised and most used pattern in our scenario. Dependency Injection is all about injecting dependencies to create a given object just as said by its name. This is all about automatically resolving the required dependencies at run time without having the client specifically looking it up and creating them and injecting them to the new object to be created. So we are delegating the whole dependency resolving to an automated mechanism, thus a very popular form of Inversion of Control principle, whereas a massive improvement over the Service Locator.

Service Locator is good enough, only for smaller scale projects, where as you register services manually and look them up on demand at run time. But when the project gets more bigger and complex, with a lot of inter-connecting service and dependencies, it is very hard to keep a track on all of them, and most likely you’ll up missing a whole bunch of required dependencies in your code. This is usually a common case when you move into patterns such as MVVM implement for your mobile project, where you deliberately loosely couple all the layers of your app project, and you could easily end up missing dependencies.

This is where Dependency Injection comes for the rescue, where as we inject the required dependencies in the constructor or as properties and delegate that whole process to an automated mechanism, which we call the “Container“. So whenever we implement a DI it always comes with a static singleton Container which manages all the dependencies and resolve them automatically at run time, and we just have to register the dependency mapping only with the container.

Now there’s so many kinds of Dependency Injection Containers out there for you to choose from, given the popularity of this pattern. Unity, Ninject, AutoFac, TinyIoC and so on are some examples. It’s also pretty straight forward to roll out our own, but for this demo I would use an existing DI Container, Unity, quite a popular counterpart in this space.

Alright then, first of all let’s add the Unity library to our solution.

Make sure to select your PCL project and all the platform specific projects when you’re adding Unity from nuget.

Let’s make use of the Dependency Injection with our IoC Container as below. Now there’s nothing to be changed in how you implement your abstract interfaces in your PCL shared project and concrete implementations in the platform specific projects. 🙂

Let’s create a static reference for our container instance.

public partial class App : Application
{
	// static DI Container instance
	public static UnityContainer Container { get; set; }

	public App()
	{
		InitializeComponent();
		MainPage = new NavigationPage(
                                new XFMyNotesAppDI.NoteListPage());
	}
	
	...
}

 

Next here’s our NoteManager which is going to handle basic Note managing functions such as loading and saving notes. 🙂 You might see something different than what we had in Service Locator.

public class NoteManager
{
	private readonly INoteReader _noteReader;
	private readonly INoteLoader _noteLoader;

	public IList<MyNote> MyNotes { get; private set; }
	
	public NoteManager(INoteLoader noteLoader, 
                                    INoteReader noteReader)
	{
		_noteReader = noteReader;
		_noteLoader = noteLoader;
		
		MyNotes = new 
                  ObservableCollection<MyNote>(_noteLoader.Load());
	}

	public void Save()
	{
		_noteLoader.Save(MyNotes);
	}
}

 

As you can see we are passing in the INoteLoader and INoteReader services to the constructor of the NoteManager, this means that NoteManger cannot exist without those parameters services. So what happens here is that, when we request an instance of the NoteManager, the IoC Container (Unity Container) will resolve those depending services instances and inject them into the NoteManager, whilst creating the NoteManager.

Look how simple and clear the NoteManager is compared to our Service Locator and Factory Pattern principles.

Also you can see that we are no longer maintaining a singleton static reference to the NoteManager like how we did in Service Locator, because we could do the same thing directly using our IoC Container as shown below. 🙂

public App()
{
	InitializeComponent();

	// resolve the NoteManager instance
	App.Container.RegisterType<NoteManager>(
                        new ContainerControlledLifetimeManager());
					 
	MainPage = 
             new NavigationPage(newXFMyNotesAppDI.NoteListPage());
}

 

That’s how we are registering our NoteManager instance with the container, and we are instructing the container to retain a single instance of it by passing in the ContainerControlledLifetimeManager() type object to it. Also its good to keep in mind there are several object life time management types in Unity Container which you could play around with.

One of the coolest things about IoC containers is that we could instruct it to how we need a certain object or a type should be managed in the run time of the app. 😉 Oh yeah, cool indeed!

Now with our Unity Container this is how you would register your Service Interfaces (INoteReader and INoteLoader) with their concrete implementations on the platform specific level.

Also something to keep in mind is that we need to instantiate our UnityContainer instance here in the platform specific level where the execution begins. 🙂

// Android implementation
protected override void OnCreate(Bundle bundle)
{
	TabLayoutResource = Resource.Layout.Tabbar;
	ToolbarResource = Resource.Layout.Toolbar;

	base.OnCreate(bundle);

	global::Xamarin.Forms.Forms.Init(this, bundle);
	
	App.Container = new UnityContainer();
	App.Container.RegisterType<INoteLoader, NoteLoaderDroid>();
	App.Container.RegisterType<INoteReader, NoteReaderDroid>();

	LoadApplication(new App());
}

// iOS implementation
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
	global::Xamarin.Forms.Forms.Init();

	App.Container = new UnityContainer();
	App.Container.RegisterType<INoteLoader, NoteLoaderIos>();
	App.Container.RegisterType<INoteReader, NoteReaderIos>();

	LoadApplication(new App());

	return base.FinishedLaunching(app, options);
}

// UWP implementation
public App()
{
	XFMyNotesAppDI.App.Container = new UnityContainer();
	XFMyNotesAppDI.App.Container.RegisterType<INoteLoader, NoteLoaderUwp>();
	XFMyNotesAppDI.App.Container.RegisterType<INoteReader, NoteReaderUwp>();

	this.InitializeComponent();
	this.Suspending += OnSuspending;
}

 

Thanks to the IoC Container you could easily access the NoteManager anywhere in your code, which will give you access to the static retained instance.

NoteManager _noteManager = App.Container.Resolve<NoteManager>();

 

And of course the services as well.

App.Container.Resolve<INoteReader>().Speak("Hello, read this!");

 

There you have it, now this clearly shows how easy it is to add more and more platform dependent services and use them in your shared code as you go on scaling up the project solution, all thanks to Dependency Injection Pattern! 😉

Specially you noticed how it simplifies our shared code compared to the Service Locator pattern. Also its worth it to notice, how using an IoC Container brings many useful features to the table that you could use to improve your code.

So again, which one should I use?

Now that should have given you a very good comparison between the use of,

  • Factory Pattern
  • Service Locator Pattern
  • Dependency Injection Pattern

Each one of those patterns have their own advantages and disadvantages, yet you may have noted a general aspect improvement over each other such as Factory Pattern < Service Locator Pattern < Dependency Injection Pattern. Let’s break it down as below.

Considering some of the negative aspects of NoteManager implementation in each pattern,

in Factory Pattern we had,

  • Maintain static singleton access to NoteManager
  • Maintain static references to the INoteLoader and INoteReader service objects
  • Use NoteManager to access INoteLoader and INoteReader service objects
  • Resolve INoteLoader and INoteReader service objects manually

in Service Locator Pattern we had,

  • Maintain static singleton access to NoteManager
  • Resolve INoteLoader and INoteReader service objects manually

in Dependency Injection Pattern we had,

  • none of the above issues

So there you can clarify my claim of general improvements over each pattern, Factory Pattern < Service Locator Pattern < Dependency Injection Pattern.

Although that’s being said, the choice of Pattern to follow is totally up to you and your requirements. As an example something like Factory Pattern or Service Locator Pattern would be good enough for a small scale projects and Dependency Injection would be perfect for large scale projects with heavy MVVM based apps which uses a lot of service dependencies and so on.

Conclusion?

So I hope my demonstration of each of the patterns and how to implement them properly in a Xamarin Forms project solution for the same app concept, may have helped you in deciding which patterns to be used in any given scenario, which uses cross-platform dependencies.

Oh once again, You may find the complete solution up on my Github repo: https://github.com/UdaraAlwis/XFCPMobilePatterns

Go ahead and play around with the app and check out how each pattern is used in the MyNotes App scenario! 😉

Cheers everyone! 😀