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>

Development