(Parte 2) Replicando IU de Aplicación de vuelos: Trabajando con XAML

¡¡¡Hola !!!💁‍♀ Continuamos en la replica de Apps 😍  En este caso, vamos a replicar un IU de una aplicación para vuelos el cual es un diseño obtenido de Dribble realizado por Gleb Kuznetsov✈. ¡Puedes darle un vistazo aqui!

Para sacarle el mejor provecho a esta serie, si aún no has visto la primera parte, te recomiendo leerla, se llama “(Parte 1) Replicando IU de Aplicación de vuelos: Preparando el proyecto para trabajar con MVVM“.


⚠ Antes de comenzar, para aprovechar al máximo la publicación, te dejaré algunas notas instructivas para que tengas una mejor experiencia reproduciendo la interfaz de usuario:

➖ Al principio verás una imagen con la interfaz de usuario original donde estará dividida por bloques tal cual y como la estaremos trabajaremos.

➖ Cada bloque presenta la imagen con el diseño explícito con el que estaremos trabajaremos (Se resaltan en un cuadro de color)

➖ En cada uno de los bloques de código podrás ver un comentario que dice: “Here add the code that is being explained in the next block”. Para mantenerte lo más enfocad@ posible, en esta parte se indica que la siguiente explicación del código va justo donde se agrega esta línea en comentarios.

➖No estaré utilizando estilos para que se puedan ver y comprender más rápido las propiedades agregadas a los difernetes componentes en el proceso de explicación.


En primer lugar, ¡Agreguemos los NuGet packages necesarios!

  • Para lograr el bloque de degradado y bordes redondeados, agregué PancakeView! 💚💕 (⚠ Usaremos este NuGet en más de un bloque, puedes identificarlo cuando haya un bloque marcado con la estrella. ⭐)

This image has an empty alt attribute; its file name is Screen-Shot-2020-05-07-at-12.18.21-AM-1024x89.png

Luego agrega el siguiente espacio de nombres en tu XAML:

xmlns:PanCake="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView"

¡Empecemos!

Vamos a dividir el diseño original en bloques

Para una mejor comprensión, he dividido el diseño original en bloques, que se enumeran en el orden en que los vamos a reproducir, estos son:

This image has an empty alt attribute; its file name is MainFlightBanner-1024x716.png


This image has an empty alt attribute; its file name is Screen-Shot-2020-05-05-at-11.10.22-PM-1024x50.png

This image has an empty alt attribute; its file name is Screen-Shot-2020-05-05-at-11.34.42-PM.png

¡Empecemos! En esta parte trabajaremos con el bloque Main Wall para replicarlo solo necesitamos agregar las siguientes partes:
 
➖ Barra de fondo azul
 
➖ Opciones de pie de pantalla
 
Como primer bloque de nuestra página, necesitamos establecer la estructura de diseño, en este caso utilizaremos un Grid.
 
 
 
<Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
             </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <!-- 1. Main Wall--> 
                <!-- Add here the "Blue box code"-->
                          <!-- Here add the code that is being explained in the next block-->
                <!-- Add here the "Footer bar"-->
        </Grid>

Una vez creada la estructura principal, vamos paso a paso para construir el primer bloque. En cada uno de ellos he agregado algunas líneas instructivas, así sabrás exactamente donde agregar el bloque de código, dichas lineas dicen: <! – Add here the “Block name” ->.

➖ Barra de fondo azul

<!-- Blue box-->
<BoxView Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" BackgroundColor="#0e3097" HeightRequest="260"/>

➖ Opciones de pie de pantalla

<!-- Footer bar-->
<Image Grid.Row="2" Grid.Column="0" Source="Keyboard" WidthRequest="30" Margin="20,0,0,30"/> 
       <PanCake:PancakeView Grid.Row="2" Grid.Column="1" BackgroundGradientStartColor="#6988f5" BackgroundGradientEndColor="#55a0f3" CornerRadius="28" HorizontalOptions="CenterAndExpand" Margin="0,0,0,30">
               <Button  Text="Book Flight" FontSize="20" FontAttributes="Bold" BackgroundColor="Transparent" HeightRequest="55" TextColor="White" WidthRequest="200"/>
        </PanCake:PancakeView>
<Image Grid.Row="2" Grid.Column="2" Source="Microphone" WidthRequest="30" Margin="0,0,20,30"/> 

This image has an empty alt attribute; its file name is Screen-Shot-2020-05-06-at-1.18.59-PM-1024x48.png

This image has an empty alt attribute; its file name is Screen-Shot-2020-05-06-at-1.27.58-PM-527x1024.png

¡Ahora continuemos con uno de mis bloques favoritos, el Fondo degradado!😍.

⭐ Dado que el objetivo de la Aplicación es que se puedan ver diferentes vuelos en un marco degradado, en este bloque usaremos un CollectionView.

¿Recuerdas el Model de vuelos creado en la primera parte de estas serie? ¡Genial! Ahora lo empezaremos a utilizar! Agregaremos un CollectionView, gracias a la propiedad ItemsSource podemos vincular fácilmente nuestros datos.(ItemsSource=”{Binding flight}”).

⚠ Importante: Por ahora agregaremos un tamaño fijo al Grid, esta indicado en el código cómo <! — WidthRequest will be changed later- ->, esto es para que puedas ver el diseño, pero en el próximo bloque  puedes remover la propiedad WidthRequest.

Aquí la implementación del código!

<!-- 2. Gradient  background-->
<CollectionView  x:Name="Colec" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Margin="0,-190,0,0"  HorizontalScrollBarVisibility="Never"
                                        ItemsSource="{Binding flight}" 
                                        VerticalOptions="CenterAndExpand"
                                        ItemsLayout="HorizontalList"  
                                        HeightRequest="{OnPlatform iOS='650',Android='540'}">
                                        <CollectionView.ItemTemplate> 
                                            <DataTemplate>
                                                 <! - WidthRequest will be changed later ->
                                                 <Grid WidthRequest="420">
                                                    <Grid.RowDefinitions>
                                                        <RowDefinition Height="*"/>
                                                    </Grid.RowDefinitions>

                                                    <StackLayout Grid.Row="0">
                                                         <PanCake:PancakeView BackgroundGradientStartColor="#4b68b4" BackgroundGradientEndColor="White" CornerRadius="20,20,0,0" IsClippedToBounds="true" HeightRequest="270" Margin="25,0,25,0"/>
                                                         <PanCake:PancakeView BackgroundGradientStartColor="White" BackgroundGradientEndColor="#f3f3f3" CornerRadius="0,0,20,20" IsClippedToBounds="true" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Margin="25,0"/>
                                                    </StackLayout> 
                                                     <!-- Here add the code that is being explained in the next block--> 
                                               </Grid> 
                                            </DataTemplate>
                                         </CollectionView.ItemTemplate>
</CollectionView>

This image has an empty alt attribute; its file name is Screen-Shot-2020-05-07-at-5.11.17-PM.png
This image has an empty alt attribute; its file name is Screen-Shot-2020-05-07-at-5.25.14-PM.png

 

En este bloque continuamos con la información del vuelo y de los pasajeros.

Como la información contenida en el bloque de vuelo completo es un poco larga la he dividido en bloques llamados “Flight information part (1 and 2,3 )” .

⚠ Importante: Aquí ya le puedes quitar el WidthRequest temporal indicado en el bloque anterior.

 

 

 

<Grid Grid.Row="0" Padding="50,30">
       <Grid.RowDefinitions>
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
           <ColumnDefinition Width="Auto"/>
           <ColumnDefinition Width="*"/>
           <ColumnDefinition Width="*"/>
           <ColumnDefinition Width="Auto"/>
       </Grid.ColumnDefinitions>

  <!--3. Flight information (Part1) : From details-->
  <Label Grid.Row="0" Grid.Column="0" Text="{Binding From}" FontSize="35" TextColor="White"/>
  <Label Grid.Row="1" Grid.Column="0" Text="{Binding FromDate}" FontSize="15" TextColor="White"/>
  <!--3. Flight information (Part1): Arrow  separator-->
  <Image Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="2" Source="Arrow" VerticalOptions="Center"/>
  <!--3. Flight information (Part1): To details-->
  <Label Grid.Row="0" Grid.Column="3" Text="{Binding To}" FontSize="35" TextColor="White"/>
  <Label Grid.Row="1" Grid.Column="3" Text="{Binding ToDate}" FontSize="15" TextColor="White"/>
  <!--3. Flight information (Part1): Airplane image-->
  <Image Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="4" Source="Airplane" WidthRequest="300" HeightRequest="160"/>

     <!-- Here add the code that is being explained in the next block--> 

</Grid>

This image has an empty alt attribute; its file name is Screen-Shot-2020-05-07-at-6.12.21-PM.png

Ahora, sigamos con el diseño del bloque “Flight information (Part 2)”.

This image has an empty alt attribute; its file name is Screen-Shot-2020-05-07-at-6.09.31-PM.png

<!--4. Flight information (Part2)-->

<!--4. Flight information (Part2) Fligth number-->
<Label Grid.Row="3" Grid.Column="0" Text="Flight" FontSize="17" TextColor="Silver"/>
<Label Grid.Row="4" Grid.Column="0" Text="{Binding Number}" FontSize="16"/>

 <!--4. Flight information (Part2): Class type--> 
<Label Grid.Row="3" Grid.Column="1" Text="Class" FontSize="17" TextColor="Silver"/>
<Label Grid.Row="4" Grid.Column="1" Text="{Binding ClassType}" FontSize="16"/>

<!--4. Flight information (Part2): Boarding--> 
<Label Grid.Row="3" Grid.Column="2" Text="Boarding" FontSize="17" TextColor="Silver"/>
<Label Grid.Row="4" Grid.Column="2" Text="{Binding Boarding}" FontSize="16"/>

<!--4. Flight information (Part2): Terminal--> 
<Label Grid.Row="3" Grid.Column="3" Text="Terminal" FontSize="17" TextColor="Silver"/>
<Label Grid.Row="4" Grid.Column="3" Text="{Binding Terminal}" FontSize="16"/>

<!-- Here add the code that is being explained in the next block--> 

This image has an empty alt attribute; its file name is Screen-Shot-2020-05-07-at-6.20.11-PM.png

La imagen tiene un atributo ALT vacío; su nombre de archivo es screen-shot-2020-05-14-at-5.15.09-pm.png

 

¿Recuerdas la información de los pasajeros que completamos en la

primera parte de este artículo?

¡Este es el momento de mostrarla! Gracias a este diseño podremos desplegar la información del pasajero de cada vuelo. En este bloque también usaremos un CollectionView.

⭐ Logramos el efecto de las imágenes redondeadas agregándole el CornerRadius con valor del 50% del indicado en la propiedad HeightRequest.

 

<!--5. Passengers--> 
<CollectionView Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="4" BackgroundColor="Transparent" Margin="0,60,0,20" WidthRequest="100"
                ItemsSource="{Binding passenger}" 
                VerticalScrollBarVisibility="Never" 
                HeightRequest="140">
                <CollectionView.ItemTemplate> 
                     <DataTemplate>
                         <Grid HeightRequest="78">
                             <Grid.ColumnDefinitions>
                                   <ColumnDefinition Width="*"/>
                                   <ColumnDefinition Width="Auto"/>
                                   <ColumnDefinition Width="Auto"/>
                                   <ColumnDefinition Width="25"/> 
                             </Grid.ColumnDefinitions>
                               <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                               </Grid.RowDefinitions>
                          
              <!--5. Passengers: Name--> 
              <Label Grid.Column="0" Grid.Row="0" Text="{Binding Name}" FontSize="20" TextColor="Black"/>
              <!--5. Passengers: Email--> 
              <Label Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Text="{Binding Email}" FontSize="{OnPlatform iOS='18', Android='15'}" TextColor="Silver"/>
              <!--5. Passengers: Seat--> 
              <Button Grid.Column="1" Text="{Binding Seat}" TextColor="White" CornerRadius="12" WidthRequest="50" HeightRequest="23" Padding="{OnPlatform Android='0,4'}" FontSize="{OnPlatform iOS='15',Android='10'}" FontAttributes="Bold" BackgroundColor="#92d5fe"/>
              <!--5. Passengers: Rounded Picture--> 
              <PanCake:PancakeView Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" CornerRadius="30" HeightRequest="60" Margin="0,2">
                 <Image  Source="{Binding Picture}" />
              </PanCake:PancakeView>
              <!--5. Passengers: Confirmationstatus--> 
              <CheckBox Grid.Column="3" Grid.Row="0" Grid.RowSpan="2" IsChecked="{Binding IsConfirmed}" IsEnabled="False" Color="#44d7b9"  HeightRequest="25" TranslationY="-17" TranslationX="-18"/>
                                                           
                         </Grid>  
                       </DataTemplate>
                     </CollectionView.ItemTemplate>
                </CollectionView>

      <!--Here add the code that is being explained in the next block--> 

This image has an empty alt attribute; its file name is Screen-Shot-2020-05-07-at-7.11.48-PM.png

Finalmente, ¡Agreguemos el bloque de Pago!

La imagen tiene un atributo ALT vacío; su nombre de archivo es screen-shot-2020-05-14-at-5.21.16-pm-1.png

<!--6. Payment information-->

 <!--6. Payment information: Total-->
<Label Grid.Row="6" Grid.Column="0" Text="Total you'll pay" FontSize="16" TextColor="Silver"/>
<Label Grid.Row="7" Grid.Column="0" Text="{Binding Total}" VerticalOptions="Start" FontSize="22" FontAttributes="Bold"/>

<!--6. Payment information: Spit payment status-->
<CheckBox Grid.Row="6" Grid.RowSpan="2" Grid.Column="1" Margin="20,0,0,0" HorizontalOptions="End" IsEnabled="False" IsChecked="True" Color="#90d0fa"/>
<Label Grid.Row="6" Grid.Column="2" Grid.RowSpan="2" Grid.ColumnSpan="2" VerticalOptions="CenterAndExpand" Text="Split payment" FontSize="19" FontAttributes="Bold"/>


 

¡Y nuestra aplicación Flight UI está lista! 😎.
 
Para ver la estructura completa del código, puede ingresar a mi repositorio de Github 😍
 
 
 
 

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s