Search
  • admin

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>

7 views

Recent Posts

See All

Xamarin Forms and iOC

In the context of a Xamarin.Forms app that uses MVVM, a dependency injection container will typically be used for registering and resolving view models, and for registering services and injecting them