Category Archives: Xamarin iOS

Creating an identical Custom Navigation Bar Back Button in Xamarin iOS…

Now there comes a time when the Developer has to override or customize the Back Button in their Xamarin iOS app. Well I’ve been there, hence let me share my experience…

Now the origin of my experience is that, I wanted to override the Back button click event of my Xamarin iOS, but since there’s no way to actually “override” the back button event, I had to completely get rid of the default back button and implement my own custom back button, but it had to be exactly similar as the original iOS back button…

45ffk

So let me ask you…

Have you ever wanted to override your Navigation Bar Back button in iOS  with Xamarin? or specially override it with an identical or similar looking custom button? may be to gain control of the Back button click event?

Then this post is for you… 😀

tumblr_inline_nl7ryzqono1rkrh6k

Custom, but Similar to the actual Back Button…

Yes that’s right, let me highlight the identical or similar looking custom back button, because it’s pretty simple and straightforward to override or replace the back button, but its a bit of struggle when you want to implement a custom back button which looks identical or similar to the original back button in iOS.

The key…

So the key things to keep in mind is that,

  • We need use an Image with a “Back Arrow” that is similar from look and size of the original back button.
  • Use similar Font size to display the Text
  • Use necessary padding and x/y values to place the Image and Text Title properly

Alright, let’s get into it…

Image with Back Arrow…

Now to find the image for the Back Arrow just google “iphone back button png” or something similar, you could easily find lots, I would recommend to use the icons8 website, which is where I got mine, https://icons8.com/web-app/15157/back

Make sure there’s no padding between the Image pixel space and the borders, in my case the image was 24×41 size

screen-shot-2017-03-02-at-1-09-15-pm

Oh another thing, make sure the Image is PNG, White color with a transparent back ground, so that you can edit the Tint as you go later if needed… 🙂

Title Text Font…

So for this one, I had to do a bit of playing around, which I found that “HelveticaNeue” and Font Size 17 is perfect for this. 🙂

Time for the coding… 😉

So let’s start off with loading the UIImage and initializing our UIButton.

// Load the Back arrow Image
var backBtnImage = UIImage.FromBundle("iosbackarrow.png");

backBtnImage = 
	backBtnImage.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);

// Create our Button and set Edge Insets for Title and Image
var backBtn = new UIButton(UIButtonType.Custom)
{
	HorizontalAlignment = UIControlContentHorizontalAlignment.Left,
	TitleEdgeInsets = new UIEdgeInsets(11.5f, 15f, 10f, 0f),
	ImageEdgeInsets = new UIEdgeInsets(1f, 8f, 0f, 0f)
};

 

And set up the necessary Edge Insets for the button Title and Image as shown above. Well those values I figured out by playing around with the positioning values for hours.. 😛 lol

Next let’s dive into the Button’s customization…

// Set the styling for Title
// You could set any Text as you wish here
backBtn.SetTitle("Back", UIControlState.Normal);
// use the default blue color in ios back button text
backBtn.SetTitleColor(UIColor.FromRGB(0, 129, 249), UIControlState.Normal); 
backBtn.SetTitleColor(UIColor.LightGray, UIControlState.Highlighted);
backBtn.Font = UIFont.FromName("HelveticaNeue", (nfloat)17);

// Set the Image to the button
backBtn.SetImage(backBtnImage, UIControlState.Normal);

// Allow the button to Size itself
backBtn.SizeToFit();

 

Alright, that’s quite a bit of code to swallow, so first we set the Title Text of the button, and keep in mind you could set any Text as you wish there, for now I’m just using “Back” text.. 🙂

Next for the Text Color in the Normal state, I have used the default Blue color variation that iOS use by default, you could also use any color you prefer as well 🙂 Next we set the Highlight state of Text to Light Gray.

As we discussed at the beginning we will use HelveticaNeue with Font size of 17 for the Title Text. And finally set the Image to the Button and allow it to fit to the required size. 😀

// Add the Custom Click event you would like to 
// execute upon the Back button click
backBtn.TouchDown += (sender, e) =>
{
	// Whatever your custom back button click handling
};

 

Now here’s something very important, we need to make sure we handle our custom back button click as shown above… 😉

So next we shall do the preparation for the Frame.

//Set the frame of the button
backBtn.Frame = new CGRect(
	0,
	0,
	UIScreen.MainScreen.Bounds.Width / 4,
	NavigationController.NavigationBar.Frame.Height);

// Add our button to a container
var btnContainer = new UIView(
	new CGRect(0, 0, backBtn.Frame.Width, backBtn.Frame.Height));
btnContainer.AddSubview(backBtn);

 

So there we are adding the Frame values to our Button, where as I’m setting the width to a quarter of the Screen width, and as of the Height, I’m retrieving the NavigationBar’s height for it.

Next we need to add our UIButton to a UIView container as show above and make sure it has the same Height and Width as our UIButton.

Time to wrap things up fellas…

// A dummy button item to push our custom  back button to
// the edge of screen (sort of a hack)
var fixedSpace = new UIBarButtonItem(UIBarButtonSystemItem.FixedSpace)
{
	Width = -16f
};
// wrap our custom back button with a UIBarButtonItem
var backButtonItem = new UIBarButtonItem("", UIBarButtonItemStyle.Plain, null)
{
	CustomView = backBtn
};

// Add it to the ViewController
NavigationController.TopViewController.NavigationItem.LeftBarButtonItems 
= new[] { fixedSpace, backButtonItem };

 

So here’s the final steps, we are wrapping our button’s uiview container inside the UIBarButtonItem by setting it to the CustomView property. And then add it to the LeftBarButtonItems , which overrides the default existing Back Button.

Now you may wonder why there’s another UIBarButtonItem with the Width set to -16 value, this is actually to forcefully push our custom back button to the edge of the Navigation Bar. 😀 So that right, it is more of a hack to get the job done… 😉

See it in action…

So here’s our Custom iOS Back Button in action… 😀

screen-shot-2017-03-02-at-12-16-10-pm

Just for the sake of comparing here’s the default system Back Button in iOS…

screen-shot-2017-03-02-at-12-15-54-pm

Looks almost identical yeah! 😀

Well, that’s it fellas!

Enjoy! 😀

PS: I may have gotten some help from these posts on StackOverflow:

http://stackoverflow.com/questions/18384488/ios-7-uibarbutton-back-button-arrow-color
http://stackoverflow.com/questions/227078/creating-a-left-arrow-button-like-uinavigationbars-back-style-on-a-uitoolba

Advertisements

Fancy Me! Here’s a Label with Rounded Corners in Xamarin Forms…

Time for something fancy, a Label with Rounded corners in Xamarin Forms! 😉

Why you’d ask? Well why not!

Sneak peak…

screenshot-1

Well look how cool that is yeah. So let’s see how we could do this.

Let the coding begin…

So as usual let’s sub-class our custom Label from the default Xamarin Forms Label control.

namespace WhateverYourNamespace
{
    public class CurvedCornersLabel : Label
    {
        ...
    }
}

 

some custom properties?

Yep we are going to be needing some custom properties to define the Radius value for the corners of the Label and then the background color for the Curved background, well of course you could use the default BackgroundColor property, but where’s the fun in that? lol 😛

public static readonly BindableProperty CurvedCornerRadiusProperty =
	BindableProperty.Create(
		nameof(CurvedCornerRadius),
		typeof(double),
		typeof(CurvedCornersLabel),
		12.0);
public double CurvedCornerRadius
{
	get { return (double)GetValue(CurvedCornerRadiusProperty); }
	set { SetValue(CurvedCornerRadiusProperty, value); }
}


public static readonly BindableProperty CurvedBackgroundColorProperty =
	BindableProperty.Create(
		nameof(CurvedBackgroundColor),
		typeof(Color),
		typeof(CurvedCornersLabel),
		Color.Default);
public Color CurvedBackgroundColor
{
	get { return (Color)GetValue(CurvedBackgroundColorProperty); }
	set { SetValue(CurvedBackgroundColorProperty, value); }
}

 

Now add the above properties inside the Custom control we just created above. As you can see as the default Radius we are setting value 12, if no explicit values were given this will be set as the corner radius of the Label. 🙂

Android stuff…

Let’s dig into the Android Renderer for our fancy Label 😉

So the Android TextView, which is the native control that corresponds with Xamarin Forms Label at run time,  doesn’t have a corner radius property.

So in order to create a Curved background in TextView we need to add Background Drawable layer.

Preferably a GradientDrawable which has the CornerRadius property where we could use to manipulate the curved corners as the background for our Label. Perfecto!

[assembly: ExportRenderer(typeof(CurvedCornersLabel), typeof(CurvedCornersLabelRenderer))]
namespace WhateverYourNamepsace.Droid
{
public class CurvedCornersLabelRenderer : LabelRenderer
{
	private GradientDrawable _gradientBackground;

	protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
	{
		base.OnElementChanged(e);

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

		// creating gradient drawable for the curved background
		_gradientBackground = new GradientDrawable();
		_gradientBackground.SetShape(ShapeType.Rectangle);
		_gradientBackground.SetColor(view.CurvedBackgroundColor.ToAndroid());
		
		// Thickness of the stroke line
		_gradientBackground.SetStroke(4, view.CurvedBackgroundColor.ToAndroid());
		
		// Radius for the curves
		_gradientBackground.SetCornerRadius(
			DpToPixels(this.Context,
			Convert.ToSingle(view.CurvedCornerRadius)));

		// set the background of the label
		Control.SetBackground(_gradientBackground);
	}

	/// <summary>
	/// Device Independent Pixels to Actual Pixles conversion
	/// </summary>
	/// <param name="context"></param>
	/// <param name="valueInDp"></param>
	/// <returns></returns>
	public static float DpToPixels(Context context, float valueInDp)
	{
		DisplayMetrics metrics = context.Resources.DisplayMetrics;
		return TypedValue.ApplyDimension(ComplexUnitType.Dip, valueInDp, metrics);
	}
}
}

 

So there you have it, we create a Drawable object with the Rectangle shape, and then we set the required properties such as Stroke Color and Corner Radius.

Now you may have noticed that I’m using exact Pixel values for the Radius value from the DpToPixels() method, this is to ensure the Radius value supports as many devices as possible without distorting the expected curve shape. And if you read my previous post, I have already talked about Device Independent Pixels and actual Device Pixels: DpToPixels and PixelsToDp for Xamarin Android…

Once the Drawable object is configured, we set it as the Background of the Label 🙂

iOS stuff…

Next is the iOS renderer for our control.

For iOS we have the UILabel that corresponds with the Xamarin Forms Label control at run time, now for the luck of it UILabel already has a property that associates with Radius of the corners, via the Layer property. So we could directly render the curved corners through those properties.

[assembly: ExportRenderer(typeof(CurvedCornersLabel), typeof(CurvedCornersLabelRenderer))]
namespace WhateverYourNamepsace.iOS
{ 
    public class CurvedCornersLabelRenderer : LabelRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement != null)
            {
                var _xfViewReference = (CurvedCornersLabel)Element;
				
		// Radius for the curves
                this.Layer.CornerRadius = (float)_xfViewReference.CurvedCornerRadius;
				
                this.Layer.BackgroundColor = _xfViewReference.CurvedBackgroundColor.ToCGColor();
            }
        }
    }
}

 

There we go, we set the Layer’s CornerRadius property with our CurvedCornerRadius value and the background color to the Layer.

Let’s try it out…

Now let’s consume this sweetness…

<StackLayout VerticalOptions="CenterAndExpand">

	<Label
	  Text="this is a normal Label"
	  HorizontalTextAlignment="Center"
	  VerticalTextAlignment="Center"
	  FontSize="14.5"
	  HeightRequest="30"
	  BackgroundColor="#20a9f8"
	  TextColor="White"/>

	<local:CurvedCornersLabel
	  Text="this is a rounded Label"
	  HorizontalTextAlignment="Center"
	  VerticalTextAlignment="Center"
	  FontSize="14.5"
	  HeightRequest="30"
	  CurvedBackgroundColor="#0040ff"
	  TextColor="White"
	  CurvedCornerRadius="15">
	</local:CurvedCornersLabel>

</StackLayout>  

 

Don’t be shy and use our awesome CurvedCornersLabel control we just created! 😀

Hit F5 and Run this thing man!

screen-shot-2017-02-19-at-12-17-13-pm  nexus-5-lollipop-screenshot-2

BEHOLD THE FANCINESS!

😀

Cheers everyone, enjoy!

PS: For them lazy ones, you may grab my github commit from here: Xamarin-Playground/XFCurvedCornersLabelControl

Awesome Xamarin Forms Label with HTML Text Formatting…

Why would you wanna use a WebView when you could use your Label to display HTML mark up text in your Xamarin Forms app? 😉

How it all started?

Well some times back I had to implement a Xamarin Forms Label which can display HTML formatted text…

The problem with Xamarin Forms Label?

Well of course you would tell me to use the FormattedText property built into Xamarin Forms Label. But before you say that do you even know how limited that property is? and you have to break up your string in to pieces and rebuild it with Span blocks, and also there’s only a few text formatting options available. Usually HTML has a ton of text formatting options, which you can even get close to with the default Xamarin Forms Span block customization.

So the default Xamarin Forms Label can not do any help at this case.

Solution?

Well we all know it’s super easy to parse HTML text to be rendererd in a Label with Android and iOS native implementation. That’s why I had to drill down to native level and come up with a Custom Label that could display HTML markup text. 😀

Without further due, let’s jump into it! 😉

Create the Custom Control…

So as usual let’s create our Custom Label by subclassing Xamarin Forms Label control.

namespace WhateverYourNamespace
{
    public class HtmlFormattedLabel : Label
    {

    }
}

 

Nothing fancy there… Next are the big stuff!

Xamarin Android implementation…

So here’s the renderer for our HtmlFormattedLabel

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

            var view = (HtmlFormattedLabel)Element;
            if (view == null) return;
            
            Control.SetText(Html.FromHtml(view.Text.ToString()),TextView.BufferType.Spannable);
        }
    }
}

 

So what we basically do here is native Android TextView through the Control property of our renderer and access the SetText() method, and  directly use the Android HTML parser to set your HTML Text.

Xamarin iOS implementation…

Next is our iOS renderer for the custom control.

[assembly:ExportRenderer(typeof(HtmlFormattedLabel), typeof(HtmlFormattedLabelRenderer))]
namespace WhateverYourNamespace.iOS
{
    public class HtmlFormattedLabelRenderer : LabelRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);
            
            var view = (HtmlFormattedLabel)Element;
            if (view == null) return;

            var attr = new NSAttributedStringDocumentAttributes();
            var nsError = new NSError();
            attr.DocumentType = NSDocumentType.HTML;
            
            Control.AttributedText = new NSAttributedString(view.Text, attr, ref nsError);
        }
    }
}

 

So here what we do is, we access the native iOS UILabel through the Control property and directly set the AttributedText property with our natively parsed HTML string. 😉

Now unlike Android, I wasn’t much familiar with iOS implementation of HTML text parsing, therefore I took some help from this thread for the above implementation How to display html formatted text in a UILabel ?.

KABOOM! EASY!

Let’s consume this Awesome Label! 😉

Alright time to use the Awesome Label we just created in Xamarin Forms!

Content = new StackLayout
{
	VerticalOptions = LayoutOptions.Center,
	Padding = new Thickness(20,0,20,0),
	Spacing = 30,
	Children = {
		new Label {
			HorizontalTextAlignment = TextAlignment.Center,
			TextColor = Color.Black,
			Text = "Welcome to the awesome HTML Formatter Label" +
			"Control by ÇøŋfuzëÐ SøurcëÇødë!"
		},
		new HtmlFormattedLabel()
		{
			FontSize = 14,
			TextColor = Color.Black,
			Text = 
			   "<html><body><Center>" +
			   "<font size='6'>" +
			   "This is a html formatted text," +
			   "so this is <b>bold text</b>... " +
			   "and this is <u>underline text</u>... " +
			   "and this is <strike>strike through text</strike>... " +
			   "and finally this is <i>italic text</i>... " +
			   "<br />" +
			   "Ops this is html line break..." +
			   "<br />" +
			   "And this is <sup>superscripted</sup> html text."+
			   "</font>" +
			   "<Center></body></html>",
		}
	}
}

 

So here I’m using our HtmlFormattedLabel control and directly setting a HTML formatted text to its Text property. 😀

Now hit F5 and Run that beautiful code! 😉

screen-shot-2017-02-05-at-4-08-31-pmnexus-5-lollipop-screenshot-3

There you have it fellas! 😀

Now you may grab this code from my github: Xamarin-Playground/XFHtmlFormattedLabelControl

Enjoy!

And pass on to another Developer by sharing it! 😉

Animate a CATextLayer in Xamarin iOS

So this is a flash post about animating CATextLayer text color, or in descriptively animating ForegroundColor property of CATextLayer. 🙂 With Xamarin iOS!

Since this is a flash post I’m not going to explain what is CALayers or Core Animations of Xamarin iOS, rather let’s just jump into the code.

Using CABasicAnimation

Here’s the code…

// animate text color with CABasicAnimation
CABasicAnimation myCAbasicAnimation = CABasicAnimation.FromKeyPath("foregroundColor");
myCAbasicAnimation.SetFrom(UIColor.Blue.CGColor);
myCAbasicAnimation.SetTo(UIColor.Purple.CGColor);
myCAbasicAnimation.FillMode = CAFillMode.Forwards;
myCAbasicAnimation.Duration = 1.0f;
myCAbasicAnimation.RemovedOnCompletion = false;

// Add the animation to your CATextLayer
_myCAtextLayer.AddAnimation(myCAbasicAnimation, null);

 

So we basically set the FromKeyPath value which is the key value string for the property you want to target in your CATextLayer, in this case the “foregroundColor” as in the Text color.

Then we set the SetFrom and SetTo values, respectively the values to be animated in between. 🙂

Then if you want to remove this animation from your CATextLater upon completion, you could set the RemovedOnCompletion property to be true. Finally add the animation to your CATextLater by calling AddAnimation() and pass in the CABasicAnimation we just created. 😀

If you want to repeat and even reverse this animation, or put it in a loop, then use the below properties. 😉

myCAbasicAnimation.AutoReverses = true;
myCAbasicAnimation.RepeatCount = Single.PositiveInfinity;

 

TADAAAA! 😀

Using CATransaction

Here’s the code…

// animate text color with CATransaction
CATransaction.Begin();
// you could set CATransaction values by the key
CATransaction.SetValueForKey(new NSNumber(1.0f), CATransaction.AnimationDurationKey);
// or you could directly use properties AnimationDuration
//CATransaction.AnimationDuration = 1.0f;
_myCAtextLayer.ForegroundColor = UIColor.Purple.CGColor;
CATransaction.Commit();

 

This rather is rather good for animating a whole group of layers or animatable properties at the same time as an animation block. CATransactions are explicit where as you begin the modification layer upon Begin() call and finishes up on Commit() call.

That’s it. 😉

I guess in future I would be posting more of these “Flash Posts”, instead of lengthy explanatory articles due to work stuff. 😦 Hope for the best! 😀

A Cool Breadcrumbs Bar with Xamarin Forms Animations…

A Breadcrumbs bar? Bread? Crumbs? Breadcrumbs? Ok I don’t wanna make you hungry right now! 😛

le Breadcrumbs bar…

But hey you know the Breadcrumbs bar we use in our UI designs! that bar kind of thingy that they put up, to indicate Navigation steps in Websites and mobile applications(not often though). Yeah that one, exactly! 😀

So the other day I had to implement a Breadcrumbs bar control with some nice animations to one of our Xamarin Forms apps… First I was like, Breadcrumbs bar? they actually use them in Mobile Apps? Well turned out to be YEAH! some still do! lol 😛

So I thought, why not give a try to Xamarin Forms Animations while I’m at it, without diving in to the native level to handle all the nice animations.

So as a result of that, let me introduce you to the Cool Breadcrumbs Bar cooked right out of Xamarin Forms Animations. 😉

This Breadcrumbs Bar control can be used to show case navigation path in your Xamarin Forms mobile applications, and you could use this as a separate ui control and add it to each page in your app, and set it to nicely animate and showcase breadcrumbs path in those pages. 😀

Now how did I do it?

In simple theory, I created a StackLayout control, which adds Labels horizontally on demand, but when the Labels are added to the StackLayout, they are being added with a nice X axis point transformation from right end of the screen to the left end using Xamarin Forms Animations. Likewise, each breadcrumb gets added next to each other one by one on demand.

breadcrumbs-completed

^^ Yep that’s the actual Breadcrumbs bar control I implemented with Xamarin Forms! 😉

Now I must inform you for the sake of the post I have done a simple implementation in a sample code, since I can not share the original implementation I did for my company project. So you should be smart enough to extract this implementation into another control and use it as a component for your pages. 😛

Now if you’re one of em lazy people, then grab my github up in here : XFBreadcrumbsBar

Let’s get into coding.

Alright create your Xamarin Forms PCL project and follow me!

namespace WhateverYourNamespace
{
    public class HomePage : ContentPage
    {
        private StackLayout _breadcrumbStackLayout;
        private ScrollView _breadCrumbsScrollView;
        private Button _addNewBreadcrumbButton;
        private Button _clearAllBreadcrumbsButton;

        public HomePage()
        {
           
        }
    }
}

 

Alright we create the HomePage and make sure to add those initial elements which we will be using later.

Create the Breadcrumbs Bar

Next lets create our simple but awesome Breadcrumbs bar implementation with the above StackLayout and ScrollView.

// le animated breadcrumbs bar
_breadcrumbStackLayout = new StackLayout()
{
	Orientation = StackOrientation.Horizontal,
	HorizontalOptions = LayoutOptions.FillAndExpand,
	Children =
	{
		new Label
		{
			HorizontalOptions = LayoutOptions.Start,
			Text = "Welcome!",
			FontSize = 15,
			FontAttributes = FontAttributes.Bold,
			TextColor = Color.Black,
		},
	},
	Padding = new Thickness(10,0,10,0),
	HeightRequest = 30,
};
_breadcrumbStackLayout.ChildAdded += AnimatedStack_ChildAdded;

// let's add that breadcrumbs stacklayout inside a scrollview
_breadCrumbsScrollView = new ScrollView
{
	Content = _breadcrumbStackLayout,
	Orientation = ScrollOrientation.Horizontal,
	VerticalOptions = LayoutOptions.StartAndExpand,
};

 

Now let me do a bit of explaining there, I have created StackLayout with Horizontal Orientation so that we could stack up our breadcrumb Labels next to each other. Then I have added a Label as the first child to showcase the first default Breadcrumb in the bar. 🙂

Next I have wrapped the StackLayout inside a ScrollView, to allow the new Breadcrumbs to be visible in case the Breadcrumbs StackLayout gets filled and more breadcrumb Labels are to be added. So that we could scroll to the end of the Breadcrumbs StackLayout and make them visible. 😉

Then notice I have subscribed the to ChildAdded event? yep that’s to handle new Breadcrumbs being added at the runtime, which we will get into later. 😀

Add the rest of tid bits for the UI

Next let’s add a title to the page and two buttons to show case the awesome Breadcrumbs bar, then put them all together into the Content of the page.

// Button for adding and removing breadcrumbs 
_addNewBreadcrumbButton =
	new Button()
	{
		Text = "Add a Breadcrumb",
		TextColor = Color.Black,
		BackgroundColor = Color.White,
		BorderColor = Color.Gray,
		BorderWidth = 2,
	};
_addNewBreadcrumbButton.Clicked += AddNewBreadcrumbButtonOnClicked;

_clearAllBreadcrumbsButton =
	new Button()
	{
		Text = "Clear Breadcrumbs",
		TextColor = Color.Black,
		BackgroundColor = Color.White,
		BorderColor = Color.Gray,
		BorderWidth = 2,
	};
_clearAllBreadcrumbsButton.Clicked += ClearAllBreadcrumbsButtonOnClicked;


// Now put em all together on the screen
Content =
new StackLayout()
{
	Padding = Device.OnPlatform(
	new Thickness(5, 40, 5, 0), 
	new Thickness(0, 20, 0, 0), 
	new Thickness(0, 20, 0, 0)),
	Orientation = StackOrientation.Vertical,
	Children =
	{
		_breadCrumbsScrollView,
		
		new Label()
		{
			VerticalOptions = LayoutOptions.EndAndExpand,
			HorizontalTextAlignment = TextAlignment.Center,
			Text = "Welcome to the Breadcrumbs Bar with Xamarin Forms !",
			FontSize = 25,
			TextColor = Color.Black,
		},

		new StackLayout() { 
			Children = { 
				_addNewBreadcrumbButton,
				_clearAllBreadcrumbsButton,
			},
			VerticalOptions = LayoutOptions.End,
			Padding = new Thickness(10,10,10,10),
		}
	}
};

BackgroundColor = Color.White;

 

Alright no need to spoon feed this part I suppose, since the basic Xamarin Forms stuff. Those Button click events we will handle next! 😉

Adding a new Breadcrumb?

Don’t you worry child! Here’s the button click event I talked about earlier, AddNewBreadcrumbButtonOnClicked.

private void AddNewBreadcrumbButtonOnClicked(object sender, EventArgs e)
{
	_addNewBreadcrumbButton.IsEnabled = false;

	// retrieve the page width
	var width = Application.Current.MainPage.Width;

	// Add the new Breadcrumb Label
	_breadcrumbStackLayout.Children.Add(new Label
	{
		// Grab some random text (as in insert whatever 
		// the text you want for your new breadrumb)
		Text = "/ " + 
		RandomWordGenerator.GetMeaninglessRandomString(new Random().Next(5, 10)),
		FontSize = 15,
		TextColor = Color.Black,
		TranslationX = width,
	});

	// Scroll to the end of the StackLayout
	_breadCrumbsScrollView.ScrollToAsync(_breadcrumbStackLayout,
		ScrollToPosition.End, true);

	_addNewBreadcrumbButton.IsEnabled = true;
}

 

Now here is where we add the new Breadcrumbs to the Breadcrumbs Bar StackLayout at run time. Pretty simple right?

Ok when you click on the “Add a Breadcrumb” button, it will first retrieve the Screen Width and then create a Label which represents a Breadcrumb and add some dummy text to it. Oh by the way to generate a dummy text I’m using this super simple static class which I created earlier you can grab it in this post : Random String Generator 

Then we are setting it’s TranslationX property to the Width of the screen, which will place this Label at the edge of the Breadcrumbs Bar StackLayout.

After adding the Label, next we are scrolling the ScrollView to the end to make the transition visible for the new Breadcrumb Label.

Now you should keep in mind that,

You can add any type of Breadcrumbs to the breadcrumbs bar, such as Buttons, Images etc… and make it look even more cooler! 😉

Next is the beautiful Animation part….

Awesome Animation…

So this is the most important part where we are animating out the Breadcrumb Label getting added to the Breadcrumbs Bar.

private void AnimatedStack_ChildAdded(object sender, ElementEventArgs e)
{
	Device.BeginInvokeOnMainThread(() =>
	{
		var width = Application.Current.MainPage.Width;

		var storyboard = new Animation();
		var enterRight = new Animation(callback: d => 
		_breadcrumbStackLayout.Children.Last().TranslationX = d,
		start: width,
		end: 0,
		easing: Easing.Linear);

		storyboard.Add(0, 1, enterRight);
		storyboard.Commit(
		_breadcrumbStackLayout.Children.Last(), 
		"RightToLeftAnimation", length: 800);
	});
}

 

So to explain a bit we are using a compound animation to animate the Breadcrumb Label’s X position from the starting point to the 0th point of the screen. Since we originally set the X position to the edge of the Screen, now we can decrease it through an Animation and bring it to the position it should be placed, which is next to the previous Child in the _breadcrumbStackLayout. 

This gets fired whenever you click on the  “Add a Breadcrumb” button and a new child gets added to the StackLayout, resulting a beautiful animation from right end of the screen to the left.

PS : You can play around with the Easing of the Animation and the timing to add beautiful animation to it. Use your imagination and go crazy! 😉

Clear the Breadcrumbs!

This is super easy!

private void ClearAllBreadcrumbsButtonOnClicked(object sender, EventArgs eventArgs)
{
	_breadcrumbStackLayout.Children.Clear();

	_breadcrumbStackLayout.Children.Add(
	new Label
	{
		HorizontalOptions = LayoutOptions.Start,
		Text = "Welcome!",
		FontSize = 15,
		FontAttributes = FontAttributes.Bold,
		TextColor = Color.Black,
	});
}

 

Just get rid of the Children in the StackLayout and add the default Breadcrumb back if you wish like I have chosen above 😉

Next is Run time!

That’s it fellas, hit F5 and watch the magic! 😀

breadcrumbs-bar-android  breadcrumbs-bar-ios

Well here’s the cool Breadcrumbs Bar control I added in my project after all the customization. 😉

screen-shot-2017-01-26-at-7-17-11-pm screen-shot-2017-01-26-at-7-17-22-pm

Here’s a little tip, I basically moved the Breadcrumb related stuff to a custom control and used them in all the app pages. So now whenever we navigate to any page the breadcrumbs bar will nicely animate itself at the page visible event. 😉

breadcrumbs-completed

So your imagination is the limit fellas!

Enjoy! 😀

The three awesome tools by Xamarin! Workbooks|Profiler|Inspector

Last Friday (20th January, 2017) I did a tech talk at Singapore Mobile .Net Developers  meetup, under the topic “The three Awesome tools by Xamarin – Workbooks/Inspector/Profiler”!

So this blog post is a recap of the stuff I talked about! 😉

First of all here are the slides.

Here we go, the recap…

The three awesome tools by Xamarin

slide1

Last few months Xamarin has been busy releasing a lot of new updates and tools for us Developers, specially since the acquisition by Microsoft, they have been exponentially improving their platform and eco-system. 😀

So today I thought of picking up three awesome tool that has been released by Xamarin last few months, which are going to be extremely useful for Xamarin Mobile Development.

slide3

So to start off with…

Xamarin Workbooks!

slide4

Why do we need Xamarin Workbooks you asked? 😮

slide5

Now Imagine you’re someone who’s trying to learn Xamarin Mobile development or may be even C# dot net development? 😀

Could be someone trying to teach someone Xamarin or dot net or may be you’re trying to demo some awesome piece of code you implemented at a presentation, along with some documentation? 😉

Or simply you’re just trying out an experimenting some piece of code before you do some actual implementation in your actual project code?

Now in all of these stations, you have to open up your IDE, open up the documentations or presentations may be and most annoyingly you have to continuously switch in between them at all times. Not to mention having to recompile and run your code at the same time you switch back and forth. 😮

Oh well what a hassle is that?

To get rid of all that hassle, we have Xamarin Workbooks now! 😉

slide6

A perfect blend of documentation and code and immediate live preview results.

Xamarin Workbooks, is a prefect solution for experimenting with Xamarin and dot net code implementations and even as a learning tool for exploring code snippets and various kinds of implementations in Xamarin and dot net.

Perfect for creating teaching guides with a sweet side by side integration of code and documentation. Whenever you create or open up a Workbook, it creates a Sandbox environment for you to do your stuff, so you could accomplish your documentation aspect and coding aspect in one single place. 😉

slide7

So workbooks packs a bunch of awesome features, such as full fledged code editor with Roslyn IntelliSense, which has similar syntax coloring just like in Visual Studio. It has in-line compiler diagnostics support as well.

Attached with a rich text editor for you to add side by side code and documentation on the go. You could also easily search and add nuget packages as you go, just like you would do in Visual Studio, and instantly preview the results in console, or any mobile emulators as you have chosen.

You can easily save an share your workbooks with anyone and they could open it up and try out as they wish.

slide12

So Xamarin Workbooks supports dot net console/WPF implementations, Xamarin Android/iOS mobile development and even Xamarin Mac development scenarios. How cool is that eh! 😉

Xamarin Profiler!

slide14

Why do we need Xamarin Profiler you asked? 😮

slide15

Now as mobile developers we need to make sure we are giving a smooth intuitive user experience for our beloved users. So in order to do that, we need to make sure our app is fully optimized for the memory usage, process usage and various resource usage without causing any excessive lags or crashes.

And even some times during the development we come across these mysterious crashes without even hitting any debug points where we need more than just the debug logs to figure out what’s causing those mysterious crashes. 😮

Another aspect is that as mobile developers we need to always focus on the over flow of the resource usage in our application at run time so that we could do the necessary improvements in our code to reduce any excessive resource usage.

Something very important to keep in mind is that when we are dealing with Xamarin Mobile Development, we have to deal with both the Xamarin dot net environment and the Native environment at run time. In that case the available native profilers we have for android and ios can not help to analyze our xamarin dot net environment. So we need something better than just native profilers for our Xamarin Mobile applications.

As a solution for all those scenarios, we have Xamarin Profiler now! 😉

slide16

Xamarin Profiler is a tool that seamlessly integrated with your Xamarin Application, collects and displays information to analyze your application at run time.

This can easily be used for finding memory leaks, resolving performance issues, monitoring resource usage at the run time, and more over to polish up your mobile app before delivering to your users.

Fun fact, is that this tool is actually based on the Mono log profiler which is a command line profiler that they previously used to analyze Mono run time applications. So what they have done is, they’ve added a bunch of improvements to it and added this intuitive UI on top of it deliver this analytical information for us developers! 😀

slide17

So there are three key features or as they call them “instruments” that’s packed along with Xamarin Profiler. 😀

Allocations instrument is used for analyzing  the memory usage of your application at any given point of time at the run time.

Time Profiler instrument is used for tracking app performance, whereas it allows you to see which function took the longest to finish its execution.

Then we have the Cycles instrument, which provides you details with memory cycles occurred at the run time. May be I should explain it a bit further…

Memory Cycles: When you’re dealing with Xamarin Mobile applications, we have this environment of managed dot net environment and the un-managed native environment, sometimes due to our bad code a bunch of objects in the memory creates references to them selves in a circular manner, which could happen inside the dot net environment or most of the time in between the dot net and the un-managed environment. So in situations like that, the Garbage collector finds it hard to break through those circular references and release those objects, which results in those objects presisting in memory and the memory usage is only going to get increased. 🙂

So thanks to Xamarin Inspector we could easily identify those memory cycles and do the necessary changes in our code to eliminate them 😉

slide18

It also packs up these additional features allowing us to further drill down into details to analyze our application run time.

Xamarin Inspector!

slide20

Why do we need Xamarin Profiler you asked? 😮

slide21

As Mobile Developers we need to make sure we deliver a beautiful pixel perfect design for our end users, and specially according to my UX lead he’s going to haunt me in my nightmares if I don’t deliver a pixel perfect UI implementation. 😀

So we always have to do the tiny changes in padding or the height or the width or may be a tiny hex value in the color and so on, whereas every time we do a change we need to recompile the project and run.

And then even if you get the app to run, you still have to go navigate to the page that you just made the changes to, which takes a lot of time.

Now I’m aware of the existence of Xamarin Forms Previewer, but if you had already tried it out, we are well aware there’s a whole bunch of bugs and issues with it when it comes to complex UI designs, which has a whole bunch of custom renderers.

So for a solution to all the above scenarios, Xamarin has given us this awesome tool, Xamarin Inspector! 😀

slide22

An awesome tool that allows you to debug and analyze or modify your application UI at run time without having to recompile your code. 😉

Something really cool about this tool is that it gives this awesome exploded 3D layers view of your application UI. Which makes it very easy to analyze the rendered layers and get rid of any extra layers to improve performance.

slide23

Xamarin Inspector has two main features, first is the REPL access. REPL stands for Read, Evaluate, Print and Loop, which allows you to inject code to your application in real time.

Then the Visual Inspector allows you to interact with your UI hierarchy in real time in an intuitive 3D view.

So that you could make necessary changes to your UI in real time and see it instantly rendered on your emulator. 😉

Something very important to keep in mind is that, with the latest update for this tool, they are providing you direct Xamarin Forms support, so no longer you have to deal with the native-rendered properties, you could easily make changes to your Xamarin Forms properties on the fly.

Conclusion

slide25

Yep that’s it fellas! now get out there and build something awesome with Xamarin! 😀

Cheers!

-Udara Alwis, out! 😛

So I played around with Xamarin Forms Control Templates!

Yes I did and I came up with something pretty cool. Do you want to change your app’s theme on demand at run time? or load a different template for your pages at run time? or even simply change the app’s colors on demand?

Oh yeah Xamarin Forms Control Template gives the answer to all of that! 😉 Here what I built with it! 😀

xf-control-templates-ios xf-control-templates-android

Pretty cool eh! 😀

So basically what I built was a simple app where you could dynamically change the App background  color theme and change the change the App theme style on demand.

As you can see you can change the color theme of the app by clicking on the color buttons and change the theme style by clicking on the theme change button, which loads a different theme for the App if you closely notice.

The honest inspiration for this is that I remember back in the days when I was installing Windows 8 in my laptop, at the first time boot up, they ask you to choose the color theme you would like to use.

installation-7

Where it presents you with a beautiful color pallet and when you click on any of those colors the whole page changes the color accordingly, so I wanted to build something like that for the fun someday. 😉

So here we go… 😀

What are Xamarin Forms Control Templates?

Xamarin.Forms control templates provide the ability to easily theme and re-theme application pages at runtime. – Xamarin Docs 

Nuff said, if you want to learn more about it, read the documents. Here I’m going to explain how you could achieve the above cool stuff using Control Templates for Xamarin Forms.

Xamarin Forms Control Templates Binding?

I have used the Binding in order to change the template color at runtime. 🙂 If you’re not familiar with this concept, you may read up here: Xamarin Docs

We are keeping a public Property for the Theme color in our ContentPage, and binding our Control Template’s color values to that property. So at the run time whenever we change the Color property, it will get reflected to whatever the Template and the background color will change accordingly. 😉

Otherwise we would have to create different Control Templates for every single color, which will be very heavy and long code, but thanks to Binding we could do it with ease as described above.

Let me walk you through…

1. Creating templates…

First of all let’s create our templates, we are going to create two templates with different styles, as show in the below screenshots of the finished implementation.

simulator-screen-shot-1-jan-2017-2-53-32-pm  simulator-screen-shot-1-jan-2017-2-53-45-pm

  1. Template Header and footer will have a background and simple Label for both header and footer.
  2. Template Header will have one label with with a white background color, and footer will have two labels with white background color.

For now just forget about the color and we will focus on the initial Template Design.

Alright now let’s get to work.

Let’s begin by creating the project, and make sure to create XAML based Xamarin Forms project. Then let’s create our Control Templates in the App.xaml file, within the Application.Resources tag by adding them to the global ResourceDictionary, so that they could be accessed in anywhere of the app at runtime.

You can create any number of templates as you wish and name them in anyways you prefer. 😉 More themes the merrier…

<Application.Resources>
<ResourceDictionary>

  <!--template theme 1-->
  <ControlTemplate x:Key="MyTemplate1">
    ...
  </ControlTemplate>

  <!--template theme 2-->
  <ControlTemplate x:Key="MyTemplate2">
    ...
  </ControlTemplate>

</ResourceDictionary>
</Application.Resources>

 

le template 1…

Alright let’s create our first Control Template.

<!--template theme 1-->
<ControlTemplate x:Key="MyTemplate1">
<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="0.1*" />
    <RowDefinition Height="0.8*" />
    <RowDefinition Height="0.1*" />
  </Grid.RowDefinitions>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="0.05*" />
    <ColumnDefinition Width="0.95*" />
  </Grid.ColumnDefinitions>

  <!--template header-->
  <!--use of template binding for color-->
  <BoxView Grid.ColumnSpan="2" Color="{TemplateBinding Parent.ThemeColor}" />
  <Label Grid.Row="0" Grid.Column="1"
         Text="this is my theme style 1"
         TextColor="White"
         VerticalOptions="Center" />
  <!--template header-->

  <!--your page content goes in here-->
  <ContentPresenter Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" />

  <!--template footer-->
  <!--use of template binding for color-->
  <BoxView Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Color="{TemplateBinding Parent.ThemeColor}" />
  <Label Grid.Row="2" Grid.Column="1"
         Text="template 1 (c) Udara Alwis 2016"
         TextColor="White"
         VerticalOptions="Center" />
  <!--template footer-->
</Grid>
</ControlTemplate>

 

There you have it, as you can see we have created a template with a Grid where we are aligning the page content in the middle  as the ContentPrensenter and the Header and Footer accordingly at top and bottom. We have added simple Labels to each Header and Footer with some text in it.

You can also notice that we are using Template property Binding to set the Background color of our Template. Color=”{TemplateBinding Parent.ThemeColor}”

So at the run time the Color will change according to the “ThemeColor” property which we will be implementing in the ContentPage.

You can use Binding to Change any property in your Control Templates thanks to awesomeness of Xamarin Forms! 😀

le template 2…

Now here’s our second Control Template.

<!--template theme 2-->
<ControlTemplate x:Key="MyTemplate2">
<Grid>
  <Grid.RowDefinitions>
	<RowDefinition Height="0.1*" />
	<RowDefinition Height="0.8*" />
	<RowDefinition Height="0.1*" />
  </Grid.RowDefinitions>
  <Grid.ColumnDefinitions>
	<ColumnDefinition Width="0.05*" />
	<ColumnDefinition Width="0.35*" />
	<ColumnDefinition Width="0.55*" />
	<ColumnDefinition Width="0.05*" />
  </Grid.ColumnDefinitions>

  <!--template header-->
  <!--use of template binding for color-->
  <BoxView Grid.ColumnSpan="4" Color="{TemplateBinding Parent.ThemeColor}" />
  <Label Grid.Row="0" Grid.Column="1"  Grid.ColumnSpan="2"
		 Text="this is my theme style 2"
		 TextColor="Black"
		 BackgroundColor="White"
		 VerticalOptions="Center" />
  <!--template header-->

  <!--your page content goes in here-->
  <ContentPresenter Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="4" />

  <!--template footer-->
  <!--use of template binding for color-->
  <BoxView Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="4" Color="{TemplateBinding Parent.ThemeColor}" />
  <Label Grid.Row="2" Grid.Column="1"
		 Text="template 2"
		 TextColor="Black"
		 BackgroundColor="White"
		 VerticalOptions="Center" />
  <Label Grid.Row="2" Grid.Column="2"
		 Text="(c) Udara Alwis 2016"
		 TextColor="Black"
		 BackgroundColor="White"
		 VerticalOptions="Center"/>
  <!--template footer-->
</Grid>
</ControlTemplate>

 

As you can see the difference of this Template is that we have added extra columns to the Grid container and added extra labels to fill in. Also you may have noticed that we are setting the Label background to White color in this template.

Alright there goes our two templates in this example. Next let’s implement the design for our ContentPage.

2. ContentPage design stuff…

So those two Template themes are now ready to be applied for any ContentPage in our App.

Next let’s lay down the design for our content page. Remember hence we are using Control Templates, we need to implement our UI in a way our page could use those templates, which is by,

having a ContentView which will position itself in the ContentPresenter in the Templates once we bind to them.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XFControlTemplateThemes"
             x:Class="WhateverYourNamespace.MainPage">

  <ContentView x:Name="contentView"
               ControlTemplate="{StaticResource MyTemplate1}">
    <ContentView.Padding>
      <OnPlatform x:TypeArguments="Thickness" iOS="0,20,0,0" />
    </ContentView.Padding>

   <!-- Your Page Content-->

  </ContentView>
</ContentPage>

 

You may have noticed that I have bound our ContentView ControlTemplate  property to one of the Templates we created in the App.xaml yeah? Yep exactly that’s because since we placed those templates in the App’s global level, we can directly access those properties from anywhere in our app. So as of the defualt ControlTemplate I have set it to the “MyTemplate1” template we created. So when the page loads it will be decorated with that. 😉

Now let’s take a look at the Page content design which will be placed inside the ContentView above. 🙂

Now keep in mind you can implement whatever the design you want to your Page body, but for this example basically we need to have a button to switch in between the two themes we created above and another bunch of buttons to change the color of those themes (something like a color pallet). So here we go…

<StackLayout VerticalOptions="CenterAndExpand" Padding="10,0,10,0">

  <Label Text="Welcome to the Dynamic Theme Changer app!"
		 HorizontalTextAlignment="Center"
		 FontSize="20"
		 VerticalOptions="Start"
		 HorizontalOptions="Center" />

  <Grid Padding="0,20,0,20">
	<Label Text="click below to change the theme on the go"
		   HorizontalTextAlignment="Center"
		   HorizontalOptions="Center" />
	<Button Text="change current theme template" Grid.Row="1"
				Clicked="OnButtonClicked" />

	<Grid.RowDefinitions>
	  <RowDefinition Height="*" ></RowDefinition>
	  <RowDefinition Height="40" ></RowDefinition>
	</Grid.RowDefinitions>
  </Grid>

  <Grid Padding="0,20,0,20">

	<Label Text="click below to change the theme color on the go"
		   HorizontalTextAlignment="Center"
		   HorizontalOptions="Center"
		   Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="10"/>

	<Button BackgroundColor="#ff0000" Grid.Row="1" Grid.Column="0" Clicked="OnColorChangeButtonClicked" />
	<Button BackgroundColor="#ff8000" Grid.Row="1" Grid.Column="1" Clicked="OnColorChangeButtonClicked" />
	<Button BackgroundColor="#ffff00" Grid.Row="1" Grid.Column="2" Clicked="OnColorChangeButtonClicked" />
	<Button BackgroundColor="#00ff40" Grid.Row="1" Grid.Column="3" Clicked="OnColorChangeButtonClicked" />
	<Button BackgroundColor="#00ffff" Grid.Row="1" Grid.Column="4" Clicked="OnColorChangeButtonClicked" />
	<Button BackgroundColor="#0080ff" Grid.Row="1" Grid.Column="5" Clicked="OnColorChangeButtonClicked" />
	<Button BackgroundColor="#4000ff" Grid.Row="1" Grid.Column="6" Clicked="OnColorChangeButtonClicked" />
	<Button BackgroundColor="#bf00ff" Grid.Row="1" Grid.Column="7" Clicked="OnColorChangeButtonClicked" />
	<Button BackgroundColor="#ff0080" Grid.Row="1" Grid.Column="8" Clicked="OnColorChangeButtonClicked" />
	<Button BackgroundColor="#ff0040" Grid.Row="1" Grid.Column="9" Clicked="OnColorChangeButtonClicked" />

	<Grid.RowDefinitions>
	  <RowDefinition Height="*" />
	  <RowDefinition Height="40" />
	</Grid.RowDefinitions>
	<Grid.ColumnDefinitions>
	  <ColumnDefinition Width="0.1*" />
	  <ColumnDefinition Width="0.1*" />
	  <ColumnDefinition Width="0.1*" />
	  <ColumnDefinition Width="0.1*" />
	  <ColumnDefinition Width="0.1*" />
	  <ColumnDefinition Width="0.1*" />
	  <ColumnDefinition Width="0.1*" />
	  <ColumnDefinition Width="0.1*" />
	  <ColumnDefinition Width="0.1*" />
	  <ColumnDefinition Width="0.1*" />
	</Grid.ColumnDefinitions>
  </Grid>

</StackLayout>

 

Behold my beautiful UI. 😉 As you can see the first button will be switching in between the themes we created before, and them there’s a whole another set of buttons (color pallet buttons) with different background colors, which points to the same click event. Those buttons will be changing the template color by changing the ThemeColor property I mentioned earlier, which we are going to implement next. 🙂

3. ContentPage code-behind…

Now this is where we put things together, in your MainPage.cs code behind. Which we are handling all the theme changes and color changes on the go. 😉

So here are what we are going to implement here…

  1. ThemeColor public property to be used by the Templates for Color changing feature
  2. Load the control templates to be used in this page for run time theme changing
  3. Handle the run time theme switching functionality (switch the themes in between the templates we created before)
  4. Handle the tun time them color switching functionality (switch the themes between different color as show in those color buttons)
public partial class MainPage : ContentPage
{
	public static readonly BindableProperty ThemeColorProperty =
		BindableProperty.Create("ThemeColor", typeof(Color), typeof(MainPage), Color.Red);
	/// <summary>
	/// Gets or Sets the theme color for the template
	/// </summary>
	public Color ThemeColor
	{
		set { SetValue(ThemeColorProperty, value); }
		get { return (Color)GetValue(ThemeColorProperty); }
	}

	private bool _originalTemplate = true;
	private ControlTemplate _myTemplate1;
	private ControlTemplate _myTemplate2;

	public MainPage()
	{
		InitializeComponent();

		_myTemplate1 = (ControlTemplate)Application.Current.Resources["MyTemplate1"];
		_myTemplate2 = (ControlTemplate)Application.Current.Resources["MyTemplate2"];
	}

	void OnButtonClicked(object sender, EventArgs e)
	{
		// switching to the next theme
		_originalTemplate = !_originalTemplate;
		contentView.ControlTemplate = (_originalTemplate) ? _myTemplate1 : _myTemplate2;
	}

	private void OnColorChangeButtonClicked(object sender, EventArgs e)
	{
		if (((Button)sender) != null)
		{
			var sender1 = ((Button)sender);

			// Change the theme color according 
			// to the selected button color
			ThemeColor = sender1.BackgroundColor;

			// this will update the ThemeColor property
			// and reflect to the Control template
		}
	}
}

 

You can see I have implemented the ThemeColor property where our Templates will be binding their Color properties to. Then take a look at the event OnColorChangeButtonClicked which is the event that is fired by the set of buttons with different colors as we implemented in the UI. So inside this event we are retrieving the button’s background color and setting that value to our ThemeColor property, which will in return reflect to the Template that has been loaded to the page at that moment.

And then in the Constructor we are loading the two templates we created before into our page by accessing the Application Resources dictionary so we can use those instances to change the them on the go.

Inside the OnButtonClicked event we are switching between the two template themes we have loaded above.

Finally hit F5!

Alright that’s it for the coding. Now save it and hit F5 to see the magical beauty of Xamarin Forms! 😉

xf-control-templates-ios  xf-control-templates-android

So you can see clearly that when you click on the “change current theme template” button, the theme immediately changes to the next template.

And then you click on any of the color pallet buttons you can see the theme background color changes accordingly. Beautiful isn’t it? 😉

There you have it fellas!

Now as for them lazy people, you could straight away grab the code up in my github: Xamarin-Playground/XFControlTemplateThemes

Enjoy and share! 😀

– Udara Alwis

Setting RelativeLayout ConstraintExpressions from XAML Styles in Xamarin Forms…

When it comes to Xamarin Forms RelativeLayout we always use Constraints, its pretty easy to add those Constraint values from C# code behind, but when it comes to XAML UI implementation, it’s not so easy.

so myself…

I have been working with XAML UI implementation for the last year or so, specially dealing with a lot of pixel perfect design, which needs a lot of customization to design from XAML. But as a developer you have to find ways to deal with those stuff. In my current project we practice a strict discipline of MVVM pattern, which we strongly separate XAML UI View and the ViewModel code. So under no exceptions we add any single C# UI code or XAML code behind implementations in our project.

complex design implementations…

When you have to deal with complex design implementations in Xamarin Forms, the best way to go is with RelativeLayout, along with Relative Constraint values for X/Y position and Height/Width values.

flag1

RelativeLayout is good…

Usually those RelativeLayout Constraint values manages to get the job done, with ease on both Android and iOS devices. But sometimes it doesn’t quite go right, specially with Android, where you have to deal with different types of screen resolutions.

layouts1

but sometimes…

So at times like that you need to specify RelativeLayout ConstraintExpression separately for iOS and Android devices. But how do you do this in XAML code?

so how?

So how do you set those ConstraintExpression right from XAML code? Styles is the answer! 😀

The trick is to create two different Styles for Android and iOS, targeting the control you need to set the RelativeLayout Constraints on.

And then on your control’s XAML declaration, you set the Style property using the OnPlatform tag accordingly for iOS and Android.

Let’s do it…

You could define these Styles on your Page level or Application level as you wish as shown below…

You can see I have created twp styles which targets the Label control type and added my Relative Layout ConstraintExpressions. 🙂 Also I have added the other Properties that I need to customize through these Styles.

<ContentPage.Resources>
	<ResourceDictionary>
		<Style x:Key="MyLabelStyleiOS" TargetType="Label">
		  <Setter Property="BackgroundColor" Value="Yellow"/>
		  <Setter Property="HorizontalTextAlignment" Value="Center"/>
		  <Setter Property="RelativeLayout.YConstraint" 
				  Value="{ConstraintExpression RelativeToParent,Property=Height,Factor=0.5}"/>
		  <Setter Property="RelativeLayout.WidthConstraint"
				  Value="{ConstraintExpression RelativeToParent,Property=Width,Factor=0.7}"/>
		  <Setter Property="RelativeLayout.XConstraint"
				  Value="{ConstraintExpression RelativeToParent,Property=Width,Factor=0.15}"/>
		</Style>

		<Style x:Key="MyLabelStyleAndroid" TargetType="Label">     
		  <Setter Property="BackgroundColor" Value="Yellow"/>
		  <Setter Property="HorizontalTextAlignment" Value="Center"/>
		  <Setter Property="RelativeLayout.YConstraint"
				  Value="{ConstraintExpression RelativeToParent,Property=Height,Factor=0.1}"/>
		  <Setter Property="RelativeLayout.WidthConstraint"
				  Value="{ConstraintExpression RelativeToParent,Property=Width,Factor=0.7}"/>
		  <Setter Property="RelativeLayout.XConstraint"
				  Value="{ConstraintExpression RelativeToParent,Property=Width,Factor=0.15}"/>
		</Style>
	</ResourceDictionary>
</ContentPage.Resources>

 

And then on the your Control that you need to set those RelativeLayout Constraints…

<Label Text="Welcome to the app!"  >
	<Label.Style>
	  <OnPlatform x:TypeArguments="Style"
				  iOS="{StaticResource MyLabelStyleiOS}"
				  Android="{StaticResource MyLabelStyleAndroid}" />
	</Label.Style>
</Label>

 

You can see how I have nested down the Style property and added the specific style according to the Platform type.

It’s very important to notice that I have added those Styles as StaticResource this is because we need to set those RelativeLayout ConstraintExpressions before the run time, while the XAML are being parsed. 🙂 Once the XAML layout is parsed, we can not set the ConstraintExpressions, since it’s not going to be rendered.

make it pretty… Generalize!

Yep the above styles are ugly, so let’s generalize it and move the common properties and constraints to a general style as below, and derive our child styles.

<Style x:Key="MyLabelStyle" TargetType="Label">
  <Setter Property="BackgroundColor" Value="Yellow"/>
  <Setter Property="HorizontalTextAlignment" Value="Center"/>
  <Setter Property="RelativeLayout.WidthConstraint"
		  Value="{ConstraintExpression RelativeToParent,Property=Width,Factor=0.7}"/>
  <Setter Property="RelativeLayout.XConstraint"
		  Value="{ConstraintExpression RelativeToParent,Property=Width,Factor=0.15}"/>
</Style>

<Style x:Key="MyLabelStyleiOS" TargetType="Label" BasedOn="{StaticResource MyLabelStyle}">
  <Setter Property="RelativeLayout.YConstraint" 
		  Value="{ConstraintExpression RelativeToParent,Property=Height,Factor=0.5}"/>
</Style>

<Style x:Key="MyLabelStyleAndroid" TargetType="Label" BasedOn="{StaticResource MyLabelStyle}">
  <Setter Property="RelativeLayout.YConstraint"
		  Value="{ConstraintExpression RelativeToParent,Property=Height,Factor=0.1}"/>
</Style>

 

There we go! now that’s beautiful. Always keep in mind to generalize the common Style properties, and here in this case the common ConstraintExpression values. 🙂

Cheers! 😀

How to add a fixed Background Image for a UIScrollView?

So recently I wanted to add a Fixed image behind a ScrollView in Xamarin Forms. Furthermore when the ScrollView is scrolling the background image shouldn’t scroll along with it, and background image should stay fixed while the content is scrolling.

Solution?

So the obvious solution would be to lay down a RelativeLayout and top of that Image, and then a ScrollView with Transparent background.

But I wanted…

but instead of laying out all those layouts and multiple controls, I wanted to achieve this right from one Control, by customizing the ScrollView accordingly.

So I got to into Coding…

So I created a Custom ScrollView control in PCL project and added the Custom Renderers for each platform iOS and Android. Although I got it working with ease in on Android by setting the Image as the Background drawable for the ScrollView, I was having some struggle with iOS.

trouble with iOS UIScrollView…

So the Xamarin Forms ScrollView’s native iOS mapped control is the UIScrollView. So I tried adding the a UIImageView to the UIScrollView from the custom renderer hoping it should get the job done according to theory.

but the background was panning across the Content size. And it started scrolling alone with the Content.

So let me walk you through what I tried and what actually worked… 🙂

1. Adding the UIImageView as a SubView

So as per the obvious solution I added the UIImage into a UIImageView and added it into the UIScrollView as a SubView as shown below. Also you may have noticed how I have called SendSubviewToBack method to place the UIImageView behind the UIScrollView.

protected override async void OnElementChanged(VisualElementChangedEventArgs e)
{
	base.OnElementChanged(e);

	if (e.NewElement != null)
	{
		var _uiImageViewBackground = new UIImageView(_uiImageBackground);

		this.AddSubview(_uiImageViewBackground);
		this.SendSubviewToBack(_uiImageViewBackground);
	}
}

 

And this was the result as you can see below..

method1

As you can see the UIImageView takes up the Height of the UIScrollView Content, not the UIScrollView actual Height, thereby resulting of the UIImageView spanning across the whole Content size. :O

2. Resizing the UIImage and adding the UIImageView as a SubView

Then I thought what if I resized the Image to the actual Height and Width of the UIScrollView and added as a Subview as show below.

Now in an iOS Custom Renderer we can not access the UIScrollView’s Bounds or Frame right from the OnElementChanged method, we need to override the Draw() method, which provides the Height and Width since it’s actually being drawn on the Parent view.

public override void Draw(CGRect rect)
{
	base.Draw(rect);

	// resize the UIImage to fit the current UIScrollView's width and height
	_uiImageBackground = ResizeUIImage(_uiImageBackground, (float)rect.Width, (float)rect.Height);

	var _uiImageViewBackground = new UIImageView(_uiImageBackground);

	this.AddSubview(_uiImageViewBackground);
	this.SendSubviewToBack(_uiImageViewBackground);
}

 

So as you can see I have resized the UIImage and added it to the UIScrollView thought a UIImageView holder.

Look at the results…

method2

Well the Background Image has been resized but the Background View still scrolls with the Content of UIScrollView. 😦

3. How about InsertSubview() ?

There are couple of methods for Adding a SubView to a View, the most common used one is the AddSubView() method which is also an alias for Add().

Then there also another method call we could use, InsertSubview(). In theory it does the same thing as AddSubView() but in a different manner where you could define a View index, in terms of which index the View should be added to in the array of sub-views in the given View.

So instead of this,

this.AddSubview(_uiImageViewBackground);
this.SendSubviewToBack(_uiImageViewBackground);

 

Let’s call the below, as you can see I’m placing our UIImageView at the very bottom of the SubViews stack by giving index 0 value.

this.InsertSubview(_uiImageViewBackground, 0);

 

Oh well what did you expect! Same result as before. 😦

4. How about InsertSubviewBelow() ?

So this method is also somewhat similar to above, where as this allows you to straightaway as a Subview, and define underneath which SubView you need to add your View in the stack. 😀

So I tried this as well. By the “this” reference I’m referring to the UIScrollView as the sibling and to tell the layout engine to place the UIImageView below the UIScrollView. 🙂

this.InsertSubviewBelow(_uiImageViewBackground, this);

 

But unfortunately the results was the same… 😦

5. What about directly setting the Background?

Frustrated with trying to add SubViews approach, I thought of directly setting the Background property of UIScrollView, specifically set the UIImage directly to the BackgroundColor Property of UIScrollView.

Well there’s no way we could set the BackgroundColor property from the Draw() method override, hence the canvas is already drawn. So we need to set it before its being drawn.

So let’s move back to the OnElementChanged method and set the BackgroundColor.

Since there’s no availability of the Height and Width values within the OnElementChanged event firing, for now we’ll just directly set the UIImage to BackgroundColor without resizing.

protected override async void OnElementChanged(VisualElementChangedEventArgs e)
{
	base.OnElementChanged(e);

	if (e.NewElement != null)
	{
			this.BackgroundColor = UIColor.FromPatternImage(_uiImageImageBackground);
	}
}

 

Oh well, look at the results. It also fills up the whole Content area, without just setting the “background” on UIScrollView.

method3

5. What about directly setting the Background with resized UIImage?

Alright now let’s get a bit serious and retry the above approach properly, by accessing the Height and Width of the UIScrollView and resizing the UIImage accordingly.

So to do this we need to tap into the place where the Height and Width first gets allocated before the Draw method. That’s by subscribing to the OnPropertyChanged() as shown below.

protected override async void OnElementChanged(VisualElementChangedEventArgs e)
{
	base.OnElementChanged(e);

	if (e.NewElement != null)
	{
		((CustomScrollView)e.NewElement).PropertyChanged += OnPropertyChanged;
	}
}

private void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
	if (propertyChangedEventArgs.PropertyName == CustomScrollView.HeightProperty.PropertyName)
	{
		// check if the Width and Height are assigned
		if (((CustomScrollView)sender).Width > 0 & ((CustomScrollView)sender).Height > 0)
		{
			// resize the UIImage to fit the current UIScrollView's width and height
			_uiImageImageBackground = ResizeUIImage(_uiImageImageBackground, (float)((CustomScrollView)sender).Width, (float)((CustomScrollView)sender).Height);

			// Set the background Image
			this.BackgroundColor = UIColor.FromPatternImage(_uiImageImageBackground);
		}
	}
}

 

So inside the OnPropertyChanged() event we are waiting till the Width and Height properties are available, as you can see we are looking for the PropertyName in the event args. Then we resize the UIImage according to the retrieved Height and Width and values of UIScrollView and set the UIImage to the Background.

method4

Now as you can see, the Background Image gets resized to the exact size of UIScrollView but the Background is still scrolling with the content. And if you notice closely, you can see the Background has repeated the Image, this is because of the UIColor.FromPatternImage() where as the UIImage gets repeated to fill the whole canvas. This means that the Background still gets spread across the whole Content area of the UIScrollView.

then I witnessed something strange….

What actually worked… (strangely though)

So meanwhile playing around with different override methods and properties, at some point….

I accidentally left the Draw() method overridden in my Custom Renderer as shown below, and moved the setting of the UIScrollView Background to the OnPropertyChanged event like I did in the previous step.

protected override async void OnElementChanged(VisualElementChangedEventArgs e)
{
	base.OnElementChanged(e);

	if (e.NewElement != null)
	{
		((CustomScrollView)e.NewElement).PropertyChanged += OnPropertyChanged;
	}
}

private void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
	if (propertyChangedEventArgs.PropertyName == CustomScrollView.HeightProperty.PropertyName)
	{
		// check if the Width and Height are assigned
		if (((CustomScrollView)sender).Width > 0 & ((CustomScrollView)sender).Height > 0)
		{
			// resize the UIImage to fit the current UIScrollView's width and height
			_uiImageImageBackground = ResizeUIImage(_uiImageImageBackground, (float)((CustomScrollView)sender).Width, (float)((CustomScrollView)sender).Height);

			// Set the background Image
			this.BackgroundColor = UIColor.FromPatternImage(_uiImageImageBackground);
		}
	}
}

//We need to override this to have the background image to be fixed
public override void Draw(CGRect rect)
{
	base.Draw(rect);
}

 

As you can see in my above code, I have just overriden the Draw() event and left it just as it is, without writing any code inside the method.

And behold! 😀 IT WORKED! 😀

bloopscrollview-on-ios-lowq

TADAA! 😀 as you can see we have successfully got it to work, a fixed background image in UIScrollView. 😉

Although this does not make any sense, how could the Background of the UIScrollView prevents itself from scaling to the size of Content size just by simply overriding the Draw() event, without even executing any code inside of it.

Either way this trick got the work done. 😀 May be this is just a bug in Xamarin or iOS. 😛

There you have it, how to add a fixed background image to a UIScrollView from custom renderer in Xamarin! 🙂

Enjoy!

An improved ScrollView control for Xamarin Forms by me, myself and I…

Alright now when it comes to the default Xamarin Forms ScrollView, its pretty much generic and limited with the simple common attributes and behaviours, and it does not deliver any specific “cool” features with it.

What’s so cool about it?

So I thought of creating my own Custom ScrollView for Xamarin Forms using Custom Renderers, which would include the following awesome features,

Bouncy Effect – Yeah you gotta admit, the bounce effect of a native scrollview is pretty fun to play with, in a User’s perspective. So I thought of enabling this feature in my custom ScrollView even when the Child Element doesn’t exceeds the ScrollView boundaries… 😉
(PS: this effect is interpreted in native Android and iOS differently)

Disabling and Enabling Horizontal and Vertical Scroll Indicators – Now sometimes these scroll bar indicators are useful but there are times which we want to hide them, as it might look ugly on the UI in certain cases. So yeah let’s have some control over it shall we? 😀

Background Image – Of course who wouldn’t like a background Image on a Scroll view eh! 😉 Well to be specific we are going to add a Fixed Background Image for the ScrollView. And note that this background Image would be fixed, and will not be scrolling with the Content of the ScrollView. (I will do another post to enable that feature).

Yes behold, me, myself and I presenting the “BloopyScrollView” why the name “BloopyScrollView”? I don’t even know. lol 😛

Implementation

Alright let’s go ahead and create our Custom ScrollView Control in the PCL project. Along with the following properties, so that we could have direct control over the above said behaviours.

Alright now expect this to be longer, since I have added the properties as Bindable Properties, so you could use them in any MVVM scenario with ease. 😀

namespace WhateverYourNamespace
{
    public class BloopyScrollView : ScrollView
    {
        public static readonly BindableProperty IsHorizontalScrollbarEnabledProperty =
        BindableProperty.Create(
            nameof(IsHorizontalScrollbarEnabled),
            typeof(bool),
            typeof(BloopyScrollView),
            false,
            BindingMode.Default,
            null);
        /// <summary>
        /// Gets or sets the Horizontal scrollbar visibility
        /// </summary>
        public bool IsHorizontalScrollbarEnabled
        {
            get { return (bool)GetValue(IsHorizontalScrollbarEnabledProperty); }
            set { SetValue(IsHorizontalScrollbarEnabledProperty, value); }
        }


        public static readonly BindableProperty IsVerticalScrollbarEnabledProperty =
        BindableProperty.Create(
            nameof(IsVerticalScrollbarEnabled),
            typeof(bool),
            typeof(BloopyScrollView),
            false,
            BindingMode.Default,
            null);
        /// <summary>
        /// Gets or sets the Vertical scrollbar visibility
        /// </summary>
        public bool IsVerticalScrollbarEnabled
        {
            get { return (bool)GetValue(IsVerticalScrollbarEnabledProperty); }
            set { SetValue(IsVerticalScrollbarEnabledProperty, value); }
        }


        public static readonly BindableProperty IsNativeBouncyEffectEnabledProperty =
        BindableProperty.Create(
            nameof(IsNativeBouncyEffectEnabled),
            typeof(bool),
            typeof(BloopyScrollView),
            true,
            BindingMode.Default,
            null);
        /// <summary>
        /// Gets or sets the Native Bouncy effect status
        /// </summary>
        public bool IsNativeBouncyEffectEnabled
        {
            get { return (bool)GetValue(IsNativeBouncyEffectEnabledProperty); }
            set { SetValue(IsNativeBouncyEffectEnabledProperty, value); }
        }


        public static readonly BindableProperty BackgroundImageProperty =
        BindableProperty.Create(
            nameof(BackgroundImage),
            typeof(ImageSource),
            typeof(BloopyScrollView),
            null,
            BindingMode.Default,
            null);
        /// <summary>
        /// Gets or sets the Background Image of the ScrollView
        /// </summary>
        public ImageSource BackgroundImage
        {
            get { return (ImageSource)GetValue(BackgroundImageProperty); }
            set { SetValue(BackgroundImageProperty, value); }
        }
    }
}

 

There we go IsHorizontalScrollbarEnabled, IsVerticalScrollbarEnabled to disable/enable Horizonal and Vertical Scrollbars.

IsNativeBouncyEffectEnabled to control the Native Bouncy effect.

BackgroundImage to set the ImageSource for the ScrollView’s background Image. And make sure to provide a proper image for this hence we will be resizing the given image in our native renderer level to fit to the background of the ScrollView.(You will see in the next steps below)

Alright let’s head over to creating the Custom Renderers associated with our BloopyScrollView.

Something to keep in mind…

So if you’re a frequent reader of my blog, you may remember sometime ago I created an Extention class for handling Xamarin Forms Images in Native code level: https://theconfuzedsourcecode.wordpress.com/2016/12/12/an-awesome-image-helper-to-convert-xamarin-forms-imagesource-to-ios-uiimage-or-android-bitmap/

Why I’m bringing this up, is because we are going to be needing it for this project. You ask why? Because we need to convert the above BackgroundImage, which is of type Xamarin Forms ImageSource.

So we need to convert that ImageSource to native UIImage or Bitmap image respectively in our Custom renderer levels. 😉

So go ahead and grab that code real quick and add it to your Native Projects. 😀

iOS Implementation

Now let’s create the Custom Renderer for the Control in Xamarin.iOS project.

[assembly: ExportRenderer(typeof(BloopyScrollView), typeof(BloopyScrollViewRenderer))]
namespace WhateverYourNamespace.iOS
{
    public class BloopyScrollViewRenderer : ScrollViewRenderer
    {
        private UIImage _uiImageImageBackground;

        protected override async void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            this.ShowsVerticalScrollIndicator = ((BloopyScrollView)e.NewElement).IsVerticalScrollbarEnabled;
            this.ShowsHorizontalScrollIndicator = ((BloopyScrollView)e.NewElement).IsHorizontalScrollbarEnabled;

            if (e.NewElement != null)
            {
                if (((BloopyScrollView)e.NewElement).IsNativeBouncyEffectEnabled)
                {
                    this.Bounces = true;
                    this.AlwaysBounceVertical = true;
                }

                if (((BloopyScrollView)e.NewElement).BackgroundImage != null)
                {
                    // retrieving the UIImage Image from the ImageSource by converting
                    _uiImageImageBackground = await IosImageHelper.GetUIImageFromImageSourceAsync(((BloopyScrollView)e.NewElement).BackgroundImage);
                }

                ((BloopyScrollView)e.NewElement).PropertyChanged += OnPropertyChanged;
            }
        }

        private void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
        {
            if (propertyChangedEventArgs.PropertyName == BloopyScrollView.HeightProperty.PropertyName)
            {
                // check if the Width and Height are assigned
                if (((BloopyScrollView)sender).Width > 0 & ((BloopyScrollView)sender).Height > 0)
                {
                    // resize the UIImage to fit the current UIScrollView's width and height
                    _uiImageImageBackground = ResizeUIImage(_uiImageImageBackground, (float)((BloopyScrollView)sender).Width, (float)((BloopyScrollView)sender).Height);

                    // Set the background Image
                    this.BackgroundColor = UIColor.FromPatternImage(_uiImageImageBackground);
                }
            }
        }

        // We need to override this to have the background image to be fixed
        public override void Draw(CGRect rect)
        {
            base.Draw(rect);
        }

        // Resize the UIImage
        public UIImage ResizeUIImage(UIImage sourceImage, float widthToScale, float heightToScale)
        {
            var sourceSize = sourceImage.Size;
            var maxResizeFactor = Math.Max(widthToScale / sourceSize.Width, heightToScale / sourceSize.Height);
            if (maxResizeFactor > 1) return sourceImage;
            var width = maxResizeFactor * sourceSize.Width;
            var height = maxResizeFactor * sourceSize.Height;
            UIGraphics.BeginImageContext(new CGSize(width, height));
            sourceImage.Draw(new CGRect(0, 0, width, height));
            var resultImage = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();
            return resultImage;
        }
    }
}

 

Inside the method we are assigning the relevant properties of our BloopyScrollView to the native control properties.

The UIScrollView which is associated with the Xamarin Forms ScrollView has the following native properties:

  • ShowsVerticalScrollIndicator: Make the vertical scrollbar visible or hidden
  • ShowsHorizontalScrollIndicator: Make the horizontal scrollbar visible or hidden
  • Bounces: Always enable the native bounce effect on iOS UIScrollView
  • BackgroundColor: Allows to set the background color for the UIScrollView or set an Image as a pattern

Also you may have noted that we are converting our Image Source BackgroundImage to a UIImage using our extension.

And then when the Height and Width are set to the Control, we are resizing the Image to fit those properties and setting that as the Background of the UIScrollView through the UIColor.FromPatternImage() which allows us to set the image as a pattern throughout the canvas of the UIScrollView.

the strange tale of getting the UIScrollView’s Fixed background in Xamarin… :O

Notice that we are overriding the Draw(CGRect rect) method, this is to have the UIScroll Background Image to be fixed within the boundaries, and not to be spanned across the Content area.

Because usually if we set the BackgroundColor property, it will span across the Content area, but strangely if we override the Draw() method, BackgroundColor would only be contained within UIScrollView’s boundaries, without spanning across the Content area. This is something I figured out while playing around with the above implementation. 😀

Alright let’s jump into Android… 😀

Android Implementation

Now let’s create the Custom Renderer for the Control in Xamarin.Android project.

[assembly: ExportRenderer(typeof(BloopyScrollView), typeof(BloopyScrollViewRenderer))]
namespace WhateverYourNamespace.Droid
{
    public class BloopyScrollViewRenderer : ScrollViewRenderer
    {
        private Bitmap _bitmapImageBackground;

        protected override async void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            this.VerticalScrollBarEnabled = ((BloopyScrollView)e.NewElement).IsVerticalScrollbarEnabled;
            this.HorizontalScrollBarEnabled = ((BloopyScrollView)e.NewElement).IsHorizontalScrollbarEnabled;

            if (((BloopyScrollView)e.NewElement).IsNativeBouncyEffectEnabled)
            {
                this.OverScrollMode = OverScrollMode.Always;
            }

            if (((BloopyScrollView) e.NewElement).BackgroundImage != null)
            {
                // retrieving the Bitmap Image from the ImageSource by converting
                _bitmapImageBackground = await AndroidImageHelper.GetBitmapFromImageSourceAsync(((BloopyScrollView)e.NewElement).BackgroundImage, this.Context);

                // resize the Bitmap to fit the current ScrollView's width and height
                var _resizedBitmapImageBackground = new BitmapDrawable(ResizeBitmap(_bitmapImageBackground, this.Width, this.Height));

                // Set the background Image
                this.Background = _resizedBitmapImageBackground;
            }
        }

        // Resize the Bitmap
        private Bitmap ResizeBitmap(Bitmap originalImage, int widthToScae, int heightToScale)
        {
            Bitmap resizedBitmap = Bitmap.CreateBitmap(widthToScae, heightToScale, Bitmap.Config.Argb8888);

            float originalWidth = originalImage.Width;
            float originalHeight = originalImage.Height;

            Canvas canvas = new Canvas(resizedBitmap);

            float scale = this.Width / originalWidth;

            float xTranslation = 0.0f;
            float yTranslation = (this.Height - originalHeight * scale) / 2.0f;

            Matrix transformation = new Matrix();
            transformation.PostTranslate(xTranslation, yTranslation);
            transformation.PreScale(scale, scale);

            Paint paint = new Paint();
            paint.FilterBitmap = true;

            canvas.DrawBitmap(originalImage, transformation, paint);

            return resizedBitmap;
        }
    }
}

 

The Android ScrollView which is associated with the Xamarin Forms ScrollView has the following native properties:

  • VerticalScrollBarEnabled: Make the vertical scrollbar visible or hidden
  • HorizontalScrollBarEnabled: Make the horizontal scrollbar visible or hidden
  • OverScrollMode: Always enable the native bounce effect on Android ScrollView
  • Background: Allows to set the background drawable for the ScrollView

As you may have noticed we are converting our Xamarin Forms Image Source BackgroundImage to a Bitmap image using our extension.

Then we are resizing out Bitmap image according to the Width and Height of the ScrollView to fit to the full background to be wrapped around a BitmapDrawable and set to the Background of ScrollView.

There you go! 😀

Let’s use it… 😉

Alright now that’s done, let’s consume this in our PCL project.

<StackLayout Padding="10,0,10,0">

	<Label Text="Welcome to Xamarin Forms!"
		   VerticalOptions="Center"
		   HorizontalOptions="Center" />

	<local:BloopyScrollView 
	IsNativeBouncyEffectEnabled="True"
	IsVerticalScrollbarEnabled="False"
	IsHorizontalScrollbarEnabled="False">
	<local:BloopyScrollView.BackgroundImage>
	  <FileImageSource File="xamarinBackgroundImage.png"/>
	</local:BloopyScrollView.BackgroundImage>
	
			<Label
			  FontSize="22"
			  HeightRequest="400"
			  Text=
			  "Whatever your text content to be displayed." />
			  
	</local:BloopyScrollView>

</StackLayout>

 

As you can see I have inserted my BloopyScrollView in a StackLayout and as the content of the ScrollView I have added Label. Well you can add any content you want or set any Height or Width as you wish.

Notice that I have set IsNativeBouncyEffectEnabled to be True as I want to see the native Bouncy effect. Then I have disabled the Vertical and Horizontal Scrollbars from the properties we added earlier. Then finally I have added the BackgroundImage and set the FileImageSource to the ImageSource type, where as I have placed the image in the native Resource folder, as you would do with any defualt Xamarin Forms Image. 😉

Now let’s see the results… 😀

bloopscrollview-on-ios-lowq  bloopscrollview-on-android-lowq

Yaay! 😀

As we expected the Vertical and Horizontal Scrollbars are disabled and our ScrollView has full native bouncy effect accordingly.

Also you can see the Background Image nicely resized itself and fit to the background of the BloopyScrollView. 😀

Happy dance! lol

Recap Stuff…

Now there’s some stuff I wanted to recap, that is you may have noticed that when I was resizing the Image, I needed the Control’s Height and Width, and where I have acquired those properties are in two different places on each Android and iOS renderers.

To be specific I have accessed the Control’s Width and Height on Android right from the OnElementChanged method, but on iOS renderer I have accessed those values from the  OnPropertyChanged method’s Height property event. 

This is because of the differences of the Rendering cycling of Android and iOS, whereas on Android right at the firing of the Custom Renderer it assigns itself Width and Height. But on iOS we have to access them indirectly by waiting till those properties are set, by listening to the OnPropertyChanged event.

Get it on Github! 😀 XFImprovedScrollView

Cheers everyone!

Pass this on to another developer to make them smile! 😀
– Udara Alwis