Xamarin Forms Challenge
I was recently given a skills assessment by a potential new client and I thought it was one of the better ones I’ve taken. This post will explain the test and how I completed it. Let me start by saying that although I’ve been a Xamarin Developer for over 5 years now I don’t consider myself a XAML expert. Partly because a few of those years were spent doing Xamarin Android or iOS and also because Xamarin Forms is constantly improving and evolving for the better. With that said, if you see a better approach or ways I can improve please let me know in the comments below.
On with the challenge:
I was asked to write the XAML for this high fidelity mockup
.
The first thing I noticed was the customized Navigation Page. This required that I write a Custom Renderer to remove the top line under the title. Here is my iOS version:
[assembly: ExportRenderer(typeof(NavigationPage), typeof(NoLineNavigationRenderer))] namespace Star8Test.iOS.Renderers { public class NoLineNavigationRenderer : NavigationRenderer { public override void ViewDidLoad() { base.ViewDidLoad(); // remove lower border and shadow of the navigation bar NavigationBar.SetBackgroundImage(new UIImage(), UIBarMetrics.Default); NavigationBar.ShadowImage = new UIImage(); NavigationBar.BarTintColor = UIColor.Clear.FromHexString("#1D1848", 1.0f); NavigationBar.TintColor = UIColor.White; NavigationBar.TitleTextAttributes = new UIStringAttributes { ForegroundColor = UIColor.White };.
Next I created a template for the custom header and added this to the App.xaml file along with custom colors and styles. Like this:
<?axml version=”1.0″ encoding=”utf-8″?>
<Application xmlns=“http://xamarin.com/schemas/2014/forms”
xmlns:x=“http://schemas.microsoft.com/winfx/2009/xaml”
x:Class=“Star8Test.App”>
<Application.Resources>
<ResourceDictionary>
<Thickness x:Key=“SmallTopMargin”>0,0,0,0</Thickness>
<Color x:Key=“ThemeBackgroundDetailColor”>#F0F0F0</Color>
<Color x:Key=“ThemeTextColor”>#000000</Color>
<Color x:Key=“NavigationBarColor”>#1D1848</Color>
<Color x:Key=“ContentBackgroundColor”>#4A63CB</Color>
<Color x:Key=“CircleColor”>#4A63CB</Color>
<Color x:Key=“ButtonEditBackgroundColor”>#CAA526</Color>
<Color x:Key=“BoxStyleViewColor”>#313a7d</Color>
<Style TargetType=“BoxView” x:Key=“BoxViewStyle”>
<Setter Property=“BackgroundColor” Value=“{StaticResource BoxStyleViewColor}“/>
</Style>
<Style TargetType=“StackLayout” x:Key=“HeaderViewStyle”>
<Setter Property=“BackgroundColor”
Value=“{StaticResource NavigationBarColor}“/>
</Style>
<Style TargetType=“Label” x:Key=“LabelStyle”>
<Setter Property=“FontSize” Value=“Micro”/>
</Style>
<Style TargetType=“StackLayout” x:Key=“ContentViewStyle”>
<Setter Property=“BackgroundColor” Value=“{StaticResource ContentBackgroundColor}“/>
</Style>
<Style TargetType=“Grid” x:Key=“GridViewStyle”>
<Setter Property=“BackgroundColor” Value=“{StaticResource ContentBackgroundColor}“/>
<Setter Property=“Margin” Value=“{StaticResource SmallTopMargin}“/>
</Style>
<Style TargetType=“Button” x:Key=“ButtonStyle”>
<Setter Property=“BackgroundColor” Value=“{StaticResource NavigationBarColor}” />
<Setter Property=“WidthRequest” Value=“148”/>
<Setter Property=“HeightRequest” Value=“33”/>
<Setter Property=“BorderColor” Value=“{StaticResource NavigationBarColor}” />
</Style>
<Style TargetType=“Button” x:Key=“ButtonEditStyle”>
<Setter Property=“BackgroundColor” Value=“{StaticResource ButtonEditBackgroundColor}” />
<Setter Property=“WidthRequest” Value=“160”/>
<Setter Property=“HeightRequest” Value=“33”/>
<Setter Property=“BorderColor” Value=“{StaticResource ButtonEditBackgroundColor}” />
</Style>
<Style TargetType=“StackLayout” x:Key=“DetailViewStyle”>
<Setter Property=“BackgroundColor” Value=“{StaticResource CircleColor}” />
</Style>
<!– TODO: Use TemplateBindings for text/icons/commands etc –>
<ControlTemplate x:Key=“HeaderFooterControlTemplate”>
<StackLayout Style=“{StaticResource HeaderViewStyle}“>
<!– Header–>
<StackLayout VerticalOptions=“Start”
HorizontalOptions=“CenterAndExpand”
Margin=“20,0,0,0” >
<StackLayout Orientation=“Horizontal”
HorizontalOptions=“CenterAndExpand”>
<StackLayout VerticalOptions=“Center”>
<Image Source=“user-1” Margin=“10,15,20,0”/>
<Label TextColor=“White”
FontSize=“Micro”
Margin=“0,7,0,0”
Text=“Amy Kimberly”/>
</StackLayout>
<Image VerticalOptions=“Center”
Source=“user-connect-icon”
Margin=“10,0,10,0”/>
<StackLayout VerticalOptions=“Center”>
<Image Source=“user-3” Margin=“10,10,20,0”/>
<Label TextColor=“White”
FontSize=“Micro”
Margin=“15,0,0,0”
Text=“Gary Gonzales”/>
</StackLayout>
</StackLayout>
</StackLayout>
<!– Content –>
<StackLayout VerticalOptions=“StartAndExpand”>
<ContentPresenter />
</StackLayout>
</StackLayout>
</ControlTemplate>
</ResourceDictionary>
</Application.Resources>
</Application>
Noticed how I used a ControlTemplate in order to easily reuse the same header on other pages.
Next I had to decide how the rest of the page should be laid out. Notice how the top of the page has a fixed section with a section line followed by what appears to be a three column grid. Therefore, I used a Vertical StackLayout as the parent followed by a Horizontal StackLayout for the fixed section and then a three column six row grid. The last row of the grid however contained a different background color than the rest of the grid. There are multiple ways to accomplish this but since I didn’t have the time for another custom renderer I decided to use a BoxView over the last row with the new color. This works because with this design I know the last row will always be the totals. If a row other than the last row needed a different style I probably would have been forced to use a custom renderer.
Here is my final XAML. Tell me what you think of my design decisions in the comments. Happy Xamarin Forms Coding!!
<?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:Star8Test”
Title=“Send Money”
x:Class=“Star8Test.SendMoney”
ControlTemplate=“{StaticResource HeaderFooterControlTemplate}”>
<ContentPage.Content>
<StackLayout Spacing=“1”>
<StackLayout Orientation=“Horizontal”
Margin=“0,30,0,0”
HeightRequest=“102”
Style=“{StaticResource ContentViewStyle}”>
<StackLayout>
<Label Margin=“20,20,10,0”
FormattedText=“Is your transaction over 9,500 USD”
TextColor=“White”
FontAttributes=“Bold”
FontSize=“Small”/>
<local:UnderLineLabel Text=“More Info?”
TextColor=“White”
LineColor=“White”
Margin=“20,-5,0,0”
HorizontalOptions=“StartAndExpand”/>
</StackLayout>
<StackLayout VerticalOptions=“Start”>
<Button TextColor=“White”
FontSize=“Small”
Style=“{StaticResource ButtonStyle}”
Margin=“0,35,15,10”
BorderWidth=“10”
Text=“Request Invoice”/>
</StackLayout>
</StackLayout>
<ScrollView>
<Grid HeightRequest=“365”
Style=“{StaticResource GridViewStyle}”
ColumnSpacing=“20”
RowSpacing=“1”>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=“25*”/>
<ColumnDefinition Width=“20*”/>
<ColumnDefinition Width=“18*”/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=“AUTO”/>
<RowDefinition Height=“AUTO”/>
<RowDefinition Height=“AUTO”/>
<RowDefinition Height=“AUTO”/>
<RowDefinition Height=“AUTO”/>
</Grid.RowDefinitions>
<BoxView VerticalOptions=“End”
Grid.Row=“4”
Margin=“0,20,0,0”
HeightRequest=“120”
Style=“{StaticResource BoxViewStyle}”
Grid.ColumnSpan=“3”/>
<StackLayout Grid.Row=“0”
Grid.Column=“0”
HorizontalOptions=“Start”>
<Label Margin=“20,30” FormattedText=“StarPay”
TextColor=“White”
FontAttributes=“Bold”
FontSize=“Small”/>
<Label Margin=“20,-33,0,30”
FormattedText=“Availabe: 3,000 USD”
TextColor=“White”
FontAttributes=“Bold”
FontSize=“Micro”/>
</StackLayout>
<StackLayout Grid.Row=“1” Grid.Column=“0”>
<Label Margin=“20,9” FormattedText=“Chase Debit”
TextColor=“Silver”
FontAttributes=“Bold”
FontSize=“Small”/>
</StackLayout>
<StackLayout Grid.Row=“2” Grid.Column=“0”>
<Label Margin=“20,38”
FormattedText=“Chase Credit”
TextColor=“White”
LineBreakMode=“NoWrap”
FontAttributes=“Bold”
FontSize=“Small”/>
</StackLayout>
<StackLayout Grid.Row=“3” Grid.Column=“0”>
<Label Margin=“20,0”
FormattedText=“Fee”
TextColor=“White”
FontSize=“Small”/>
<local:UnderLineLabel Text=“What’s this?”
TextColor=“White”
LineColor=“White”
Margin=“20,-5,20,0”
HorizontalOptions=“StartAndExpand”/>
</StackLayout>
<StackLayout Grid.Row=“4”
HorizontalOptions=“Start”
Grid.Column=“0”>
<Label Margin=“20,50,0,0”
FormattedText=“Payment Total”
TextColor=“White”
LineBreakMode=“NoWrap”
FontAttributes=“Bold”
FontSize=“Small”/>
</StackLayout>
<StackLayout HorizontalOptions=“End”
Grid.Row=“0” Grid.Column=“1”>
<Label Margin=“0,30,20,0”
FormattedText=“5,000 USD”
LineBreakMode=“NoWrap”
TextColor=“White”
FontSize=“Small”/>
</StackLayout>
<StackLayout Grid.Row=“1”
HorizontalOptions=“End”
Grid.Column=“1”>
<Label Margin=“0,10,20,0”
FormattedText=“0 USD”
LineBreakMode=“NoWrap”
TextColor=“Silver”
FontSize=“Small”/>
</StackLayout>
<StackLayout Grid.Row=“2”
HorizontalOptions=“End”
Grid.Column=“1”>
<Label Margin=“0,40,20,0”
FormattedText=“1,000 USD”
LineBreakMode=“NoWrap”
TextColor=“White”
FontSize=“Small”/>
</StackLayout>
<StackLayout Grid.Row=“3”
HorizontalOptions=“End”
Grid.Column=“1”>
<Label Margin=“0,0,20,0”
FormattedText=“15.00 USD”
TextColor=“White”
FontAttributes=“Bold”
LineBreakMode=“NoWrap”
FontSize=“Small”/>
</StackLayout>
<StackLayout Grid.Row=“4”
HorizontalOptions=“End”
Grid.Column=“1”>
<Label Margin=“0,48,20,0”
FormattedText=“6,000 USD”
TextColor=“White”
LineBreakMode=“NoWrap”
FontAttributes=“Bold”
FontSize=“Medium”/>
</StackLayout>
<StackLayout Grid.Row=“0”
Grid.Column=“2”>
<Button TextColor=“White”
FontSize=“Small”
Style=“{StaticResource ButtonStyle}”
Margin=“0,32,15,10”
BorderWidth=“10”
Text=“Edit”/>
</StackLayout>
<StackLayout Grid.Row=“1”
Grid.Column=“2”>
<Button TextColor=“White”
FontSize=“Micro”
Style=“{StaticResource ButtonEditStyle}”
Margin=“0,5,15,10”
BorderWidth=“10”
Text=“Select”/>
</StackLayout>
<StackLayout Grid.Row=“2”
Grid.Column=“2”>
<Button TextColor=“White”
FontSize=“Small”
Style=“{StaticResource ButtonStyle}”
Margin=“0,32,15,10”
BorderWidth=“10”
Text=“Edit”/>
</StackLayout>
<StackLayout Grid.Row=“4”
HorizontalOptions=“End”
Grid.Column=“2”>
<Label Margin=“0,50,20,0” FormattedText=“15.00 USD”
TextColor=“White”
LineBreakMode=“NoWrap”
FontSize=“Small”/>
<Label Margin=“15,-5,0,0” FormattedText=“Fee Total”
TextColor=“Silver”
LineBreakMode=“NoWrap”
FontSize=“Micro”/>
</StackLayout>
</Grid>
</ScrollView>
<StackLayout HorizontalOptions=“Center”
Orientation=“Horizontal”
Margin=“0,15,0,0”
Style=“{StaticResource HeaderViewStyle}”
VerticalOptions=“End” >
<Label Text=“Next”
FontSize=“Large”
TextColor=“White”></Label>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
You must be logged in to post a comment.