Xamarin, Web & Mobile Software Developer/Engineer

Menu

Xamarin

I’ve actually had this project around since this start of the year but I never blogged it. I did this code for my speaking session at Microsoft Ignite in Australia.

Warning – This code is a playground there’s lots of play code and not reflective of a production application. This project is for only used for learning about Xamarin.Forms features.

In this blog post I’ll go over some of the features want to demo with this app, with some screenshots. Over the coming weeks I plan to demonstrate that anyone who says you cannot build fast and beautiful apps in Xamarin.Forms is simply wrong, lying or ignorant. The deal is that you just need to know how Xamarin.Forms work.

Post-Layout Animations/Translations – Right Slide Bar

One of the most powerful features of Xamarin.Forms are the Post-Layout translations.

People are so surprised when I tell them this is done without any custom renders, let’s take a look at how.

In this case I make use of the Grid in Xamarin.Forms, in actual fact the sidebar is layered over the listview which in the background. The Grid only has a single column.

1

2

3

4

5

<Grid>

<FriendList...(300Set Width)

<Header...(Full Screen Width)

<ListView...(Full Screen Width)

</Grid>

So the FriendList normally sits on top of the List but what we actually do is translate the X coordinate so it sits off the screen, just after the page size allocated.

1

2

3

4

5

6

protectedoverride voidOnSizeAllocated(doublewidth,doubleheight)

{

base.OnSizeAllocated(width,height);

friendList.TranslationX=this.Width;

}

Then the awesomely simple part, when a user taps the menu button we just translate the views.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

voidFriendListTapped(objectsender,System.EventArgse)

{

if(friendList.TranslationX==Width)// determine if open

{

friendList.TranslateTo(Width-300,0,100);//open the friendlist

myListView.TranslateTo(-300,myListView.TranslationY,100);//move the listview to allow for friendlist

header.TranslateTo(-300,header.TranslationY,100);//move the header to allow for friendlist

}

else

{

friendList.TranslateTo(Width,0);//close the friendlist

header.TranslateTo(0,header.TranslationY,100);//put the header back

myListView.TranslateTo(0,myListView.TranslationY,100);//put the listview back

}

}

Disappearing NavigationBar

This one was a little harder and it’s still not working perfectly.

In this case our grid has 2 rows, 80 at the top for the header size and a * for the rest.

While the ListView actually uses the Grid.RowSpan=”2″ so it goes over multiple rows, I had to do this because the height of the listview needs to be the full height of the screen once the header disappears. I also make use of the ability to set post-layout values in Xaml, setting the TranslationY to 60 on the ListView (this moves it down into the correct position by default).

So when we want to hide the navigation bar we must hook into the Scrolled event on the listview and translate the Y values on the views depending on the scroll position. This part is really just for a demo, it’s not thought out and very prototype.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

voidMyListView_Scrolled(Point obj)

{

varheaderHeight=60;

if(obj.Y<=0)

{

header.TranslationY=0;

myListView.TranslationY=headerHeight;

}

elseif(obj.Y<=headerHeight)

{

header.TranslationY=-obj.Y;

myListView.TranslationY=-obj.Y+headerHeight;

}

elseif(obj.Y>headerHeight)//scrolled

{

header.TranslationY=-headerHeight;

myListView.TranslationY=0;

}

}

Like Animations

One other thing I like about this app is the animated likes buttons.

In this case I cheated a little bit and used a Animated Gif, it worked ok. I also used a few other features.

As with all the other cases I leveraged the Grid. You’ll also notice that I used a few extra controls, AdvancedFrame from FreshEssentials to allow for the rounded edges and a GifImageViewControl.

Normally I like to write about deep technical topics but CX (Customer Experience) is another one of my passions. I’m passionate about CX because I’ve had so many bad experiences with big brands and this trend is a welcome change.

A DoD or Definition of Done is a software development term, the term is common in many agile teams and it has origins in SCRUM. The basic idea is that a team has a shared understanding of what defines a task as Done. What a project manager might foresee as ‘Done’ can be different to a developer or a customer. At XAM Consulting we deliver high quality solutions for our customers and therefore a solid DoD is essential. It’s important all developers understand that just because they’ve made a code change this does not mean it’s done.

We’ve recently revised our Definition of Done and thought we would share it because it’s a good marker on what it means to be ‘Done’ as a Xamarin developer.

Note* This is only a checklist for what’s done as a developer, it’s not the complete software lifecycle, in order for this to be successful we also need to follow modern software engineering techniques including gitflow, CI and TestCloud Testing.

So here I present… The Definition of Done (DoD) for Xamarin developers. (This DoD could also apply for Mobile Developers or Cross Platform developers)

Code respects XAM Consulting’s Code Quality and Architecture GuidelinesWe’ve not published this in the public domain (yet) but in summary we follow industry best practices for code quality. Our code bases are designed to be maintainable in the long term. Here’s a short summary:

Code is Loosely Coupled

Code has High Cohesion

Code makes use of OOP (avoiding pitfalls with inheritance, prefer composition over inheritance)

Interface Driven Development – programming to small interfaces

Classes are small

Methods are small

Code follows SOLID Principles

Use and understand design patterns

Make use of Reactive patterns

Tested on all target platformsAs our solutions are cross platform it’s essential that all code modifications are tested on all target platforms. If you test on a single platform it’s not done.

Tested on variety of screen sizesIt’s easy to code a UI for a single screen size but much harder to have it work on multiple sizes, especially smaller devices. All code modifications must be tested on different screen sizes.

Tested on a variety of physical devicesReal devices behave differently to simulators in many situations. All code modifications must be tested on a variety of devices, internally at XAM Consulting we have a good variety of different physical devices for internal testing before we go into TestCloud.

All possible side effects tested in systemIf you make modification in a complex system it’s essential that you test for any possible side effects.

Tested in Release ModeApplications can behave much different in Debug mode then Release. We need to make sure we’re testing the application in a release mode.

Application must handle intermittent connectionsMobile devices have transient connections, there needs to be a strategy for handling these types of connections.

Units TestsUnit tests are an essential component of a high quality codebase. If it doesn’t have unit tests it’s not done.

UITests developed covering featuresXamarin TestCloud is a great tool, it’s saved us (from production issues) a number of time. We now have UITests and CI with (TestCloud) on all of our projects.

Peer reviewed codeThis is a no brainer, peer reviewed code is essential. We made this a part of our lifecycle using gitflow.

Peer reviewed for end-user acceptanceIt’s important that not only the code is reviewed we also need to ensure that the problem is well understood. It’s important that two or more people discuss and understand the issue. Once understood the developers must both test the solution will meet the user acceptance criteria.

Issues must be reproducedIf you don’t reproduce an issue it cannot be confirmed as solved. The issue that is reproduced must be exactly the same as the issue that’s reported, otherwise there might be two issues.

Essentially, the goal is to have no issues when shipped into a UAT environment. If you ship a issue into UAT you need to review why that issues went into UAT.

At XAM Consulting it’s our commitment to ship world class apps and I hope that you can also make the effort.

If you’re a Xamarin.Forms developer, it’s likely you already know about the two great talks that Jason Smith did at Evolve this year (2016). Both of the talks were on performance in Xamarin.Forms and they were outstanding because we got a truckload of performance tips that we’ve never had previously. If you’ve watched them once we would recommend you also consider watching them again, there’s alot of content and you’ll learn something new. This insight into the Xamarin.Forms performance and the layout system has been a key part of us building performant apps in Xamarin.Forms at XAM Consulting.

But we wanted more, we wanted more speed and more performance, we want native performance. The tips we got were great, but we wanted to understand why these tips existed because if we understand the system we can use that understanding to develop our own tips and techniques for Xamarin.Forms performance.

One of the points that Jason makes is about the Xamarin.Forms Grid, the suggestion is that we should avoid using the ‘Auto’ setting for columns and rows. Why is this? Well it turns out that if a view inside a Auto column changes size (or generally does anything to invalid measure) the grid will be doing a full layout of all children, well not only the grid but the Grid’s parent and parent after that.

If you watch both of the talks, it’s clear the root of performance in Xamarin.Forms is in the layout system, so let’s look into this Layout System. Now that Xamarin.Forms is open source we can use the code a understand the layout system.

The layout system is broken up into two parts/cycles, 1) the invalidation cycle 2) the layout cycle.

Invalidation Cycle

To understand the invalidation cycle let’s take a look at the Xamarin.Forms layout code.

As we can see in this code below each VisualElement.cs has a event MeasureInvalidated, VisualElement is the base class of Layouts, Views and Pages.

Then each time a child is added to a Page or Layout, the parent attaches the MeasureInvalidated event of the child.

As we can see below the OnChildMeasureInvalidated event handler (for the children) then calls the MeasureInvalidated event, because the parent of that View is subscribed to the MeasureInvalidated even the parents OnChildMeasureInvalidated method is called. It’s important to note there’s conditional logic involved, the event will not always be called.

…Conditional Logic…

So here’s an example of what it looks like, with the events.

Here’s what happens when a child view becomes invalidated. As you can see the events bubble to the top.

That’s the invalidation cycle.

Layout Cycle

Let’s take a look at the layout cycle, the layout cycle happens in two cases:
1) When a layout is done for the first time, eg. when a page is first displayed.
2) After the invalidation cycle

As you can see in the image below, during the first part of the layout cycle measure is called on the child. It’s important to note that for the most part measure is called on all children and in many cases it’s called multiple times. After the children have been measured then layout is called on all children.

So here’s how the full layout looks.

You might be thinking why do I care about this? Well because we can hack it. It’s possible to short circuit the invalidation cycle at an early stage, as per the image below.

Let’s take a look at how we can test this. In order to test this I’ve created a page with a few labels and a single label that’s, updated on a timer 20 times. I’ve also linked up my Xamarin.Forms app into the Forms code base and added performance metrics to the methods inside Forms.

Let’s first take a look at the results of a StackLayout as per below.

The results show that LayoutChildIntoBoundingRegion is called 243 times, every time the text of the label is changed a full layout cycle happens.

Let’s try the same with a Grid, as per below.

The results show that LayoutChildIntoBoundingRegion is called 6 times, it’s only called the first time the view is shown.

Let’s try the same Grid but using a ‘Auto’ for a row.

The result is back up to 243 times and the full layout is happening every time the label text is changed.

Ok, now let’s put back the Grid to using stars but I also want to try something different. I want to have children of the grid dynamically change size, so let’s test with a BoxView that changes width.

NB – In order for me to change the Width of the Box I need to change the HorizontalOptions on the BoxView from Fill to Start.

Even though we’ve changed the Height back to a star the result is still 243 and the full layout is happening everytime the label text is changed. It seems that when we change the HorizontalOptions of a child we also change change the invalidation cycle behaviour.

Ok, so I changed the BoxView back to Fill the BoxView will not change dynamically. Let’s try something different, lets put the BoxView inside a ContentView.

It’s back down again, great so we still get our children changing dynamically and we also short circuit the layout system.

Conclusions

A child of a stacklayout will always cause a full layout cycle, there’s no way a StackLayout can short circuit this cycle.

A child of a Grid with that’s inside rows and columns with static or star widths AND the LayoutOptions are set to Fill, are fully constrained which means that the invalidation cycle will be stopped at that child view.

In order to have children of a Grid change layout dynamically they need to be a child of another View which is fully constrained. (As per the Grid sample).

After taking a look at the Xamarin.Forms code base I can see this is the line that does the short circuit. It seems that a view.Constraint needs to be the value of LayoutConstraint.Fixed for this short circuit to occur. I did further research into this and found the only time we can short circuit the invalidation cycle is in the cases proven above.

UPDATE – Originally in this blog post I mentioned that the above cases are the only way to short circuit the invalidation cycle, this is not entirely true as the AbsoluteLayout can be used to short circuit the invalidation cycle. I will put together some more research for this for another post.

Last weekend I was lucky enough to attend and speak at the Xamarin Dev Days in Singapore. I think Dev Days Singapore is the biggest Dev Days so far with 400 registrations and 250 that attended. It was even more awesome for myself as I got to catch up with some friends in the Xamarin world including Rui Marinho.

In this video I talk with Rui Marinho the founder of XLabs and now a developer on the Xamarin.Forms team. We delve into some important topics, we discuss how he got into Xamarin, announce that XLabs is Dead, talk about open source and a little about the future of Xamarin.Forms.

In this video I interview Matthew Robbins the creator of MFractor a Xamarin Studio Plugin. If you’re not using MFractor your really missing out, it’s got some beautiful features which save you truckloads of time when building apps with Xamarin Studio.

If you’ve ever wanted a ReSharper for Xamarin Studio this is it. It’s got static analysis, code generation and advanced navigation features. It’s here right now and will only get more awesome into the future.

Your favourite Mvvm Framework for Xamarin.Forms just keeps getting better. At XAM Consulting we use FreshMvvm in all of our serious production applications, the fact that we use FreshMvvm so intensely is the reason that FreshMvvm is easy to use, robust and flexible.

There’s been two releases of FreshMvvm since I last updated, Version 2.1 and Version 2.2.

Release 2.2.0

Better debug messages displayed

In previous versions of FreshMvvm construction errors of pages were in a few levels of inner exceptions, so if your xaml had a little error you had to dig into the inner exceptions. It was not an issue for experienced users of FreshMvvm but for people new to the Framework it was a bit hard to figure out the actual issue. Now exceptions will be bubbled up developers won’t need to look into inner exceptions.

Ability to remove a page from Navigation

In some cases you might want to remove a page from the Navigation stack. This works in the case you’ve Pushed a few pages but want to remove one of the pages from the stack before you return, for example you’ve pushed to Page1 -> Page2 -> Page3, but you essentially you don’t want Page2 to be part of the stack anymore. In this case you can call the remove method.

C#

1

CoreMethods.RemoveFromNavigation<Page2ViewModel>();

Add ability to SwitchSelectedRoot page in Tabs and MasterDetail

This is another special finite feature of FreshMvvm, in which you can switch the currently selected page of the main tabbed page or the master detail page.

C#

1

2

3

4

5

6

7

8

//switch the selected tab to the HomePageModel

CoreMethods.SwitchSelectedTab<HomePageModel>();

//switch selected master to the HomePageModel

CoreMethods.SwitchSelectedMaster<HomePageModel>();

//switch selected to the HomePageModel

CoreMethods.SwitchSelectedRootPageModel<HomePageModel>();

Release 2.1.0

Adds ability to control PageModel mapping via PageModelMapper

You now have the ability to control the convention of mapping ViewModel to pages. You do this by using the IFreshPageModelMapper.

C#

1

2

3

4

publicinterfaceIFreshPageModelMapper

{

stringGetPageTypeName(Type pageModelType);

}

Currently the PageModel mapper is defaulted to the FreshPageModelMapper.

It’s easy to implement your own custom mapper and then set the PageModelMapper.

C#

1

FreshPageModelResolver.PageModelMapper=MyPageModelMapper();

Adds ability to navigate without animation

You can now push and pop PageModel without animations.

Better cleanup of objects

We clean up after ourselves, even better now.

IOC now has unregister feature

You can now unregister a class out of the IOC container.

Add First Only Tabbed Navigation Container

FreshMvvm has always had a built in tabbed navigation container, the behaviour of this navigation is to keep the tabs always present but this is not what you always want. In some case you want the tabs to disappear when you push to a page, so we created the FreshFONavigationContainer. The FO stands for First Only and it means this tab page will only appear on the first page of the app.

FreshMvvm in Production

It makes us happy to see that so many others are also delivering great apps using FreshMvvm. I was recently informed that the Fraedom Expense app was built with FreshMvvm. Great work.

Switching out NavigationStacks on the Xamarin.Forms MainPage

There’s some cases in Xamarin.Forms you might want to run multiple navigation stacks. A good example of this is when you have a navigation stack for the authentication and a stack for the primary area of your application.

To begin with we can setup some names for our navigation containers.

C#

1

2

3

4

5

publicclassNavigationContainerNames

{

publicconststringAuthenticationContainer="AuthenticationContainer";

publicconststringMainContainer="MainContainer";

}

Then we can create our two navigation containers and assign to the MainPage.

Ah this is one I’ve been wanting to do for a long time and I’m pretty excited about it. We use it everyday, as it’s really useful.

FreshEssentials for Xamarin.Forms has ONLY the most common elements you need for Xamarin.Forms. It’s contains the elements you need in almost every project and nothing more, things like BindablePicker, SegementedButtons, InverseBooleanConverter, TappedGestureAttached, ListViewItemTappedAttached and not much more. It’s the lightweight essentials.

Why?

Because it’s awesome and nothing else solves this problem yet. For the majority of projects there’s some missing essential pieces to the Xamarin.Forms puzzle, what I wanted to build was a nuget that filled the gaps but ONLY the essential gaps. These are code snippets I’ve been putting in the majority of my Xamarin.Forms projects, the components are stable and used regularly. These codes snippets include a BindablePicker and InverseBooleanConverter, who doesn’t use them in a project. Most people just copy them from project to project, XLabs had the idea to solve this issue but now it’s blow out and is normally too large for most Xamarin.Forms projects. Just to note, I’m a contributor to XLabs and was one one of the first to contributors but with the direction it’s now taken I’m not sure if anyone wants to maintain it, the monolith it is means it’s hard to maintain.

How to use?

nuget all the things…. Primarily you can get FreshEssentials from nuget.

AdvancedFrame (flexible rounded corners)

This is primary used for the SegmentedButtonGroup, it gives you more flexibility on the corner radius in the Frame. AdvancedFrame inherits from Frame, you can set corner type via Corners(There are only four type, left, right, all, none), you can also set CornerRadius and InnerBackground color

<Label Text="Corners is left, CornerRadius is 10, InnerBackground is Blue"TextColor="White"/>

</fe:AdvancedFrame>

SegmentedButtonGroup

This is one that most people ask for in their first project, normally people fail to implement the segmented button in XF and crosss platform. I hope with this control people will be able to use it more often.

SegmentedButtonGroup is like iOS Segmented Controls, you can binding SelectedIndex for it