Xamarin.Forms Shell

A finales de mayo, Microsoft lanzó la versión Xamarin.Forms Shell, un shell destinado a simplificar la creación de aplicaciones móviles multiplataforma e incluye la siguiente funcionalidad: menú lateral, pestañas, navegación, búsqueda.

Comencemos creando un proyecto Xamarin.Forms vacío en Visual Studio 2019. Tenga en cuenta que, por el momento, Shell admite oficialmente solo 2 plataformas: iOS y Android, UWP todavía está en desarrollo. Recomiendo actualizar inmediatamente todos los paquetes nuget en la solución.



A continuación, crearemos la clase AppShell derivada de Shell, para esto agregaremos el archivo XAML al proyecto general con los siguientes contenidos:

AppShell.xaml

<?xml version="1.0" encoding="utf-8" ?> <Shell xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloShell.AppShell"> </Shell> 

AppShell.xaml.cs

 namespace HelloShell { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class AppShell : Shell { public AppShell() { InitializeComponent(); } } } 

luego en el archivo App.xaml.cs indicamos que AppShell actuará como MainPage:

 public App() { InitializeComponent(); //MainPage = new MainPage(); MainPage = new AppShell(); } 

y un par de páginas de ContentPage: Página1 y Página2. Además, las imágenes se utilizarán en nuestra aplicación de prueba, por lo que las agregaremos a proyectos dependientes de la plataforma, para los androides en la carpeta de recursos Resources => y para ios en la carpeta de Recursos.



Menú lateral




El menú lateral (a menudo llamado menú de hamburguesas) es un menú emergente que se puede abrir presionando un botón o con un gesto especial e incluye un encabezado (Encabezado), una lista de páginas (Elementos flotantes) y un menú (Menú flotante)

AppShell.xaml

 <?xml version="1.0" encoding="utf-8" ?> <Shell xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:pages="clr-namespace:HelloShell" x:Class="HelloShell.AppShell"> <Shell.FlyoutHeader> <StackLayout BackgroundColor="White" Padding="10"> <Image HeightRequest="100" Source="xamarin.png" /> <Label Text="Header" /> <Label Text=" !"/> </StackLayout> </Shell.FlyoutHeader> <FlyoutItem Title="MainPage" Icon="xamarin.png"> <ShellContent ContentTemplate="{DataTemplate pages:MainPage}"/> </FlyoutItem> <FlyoutItem Title="Page1" Icon="xamarin.png"> <ShellContent ContentTemplate="{DataTemplate pages:Page1}"/> </FlyoutItem> <FlyoutItem Title="Page2" Icon="xamarin.png"> <ShellContent ContentTemplate="{DataTemplate pages:Page2}"/> </FlyoutItem> <MenuItem Clicked="MenuItem_Clicked" Text="" IconImageSource="item.png" /> </Shell> 

AppShell.xaml.cs

 namespace HelloShell { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class AppShell : Shell { public AppShell() { InitializeComponent(); } private async void MenuItem_Clicked(object sender, System.EventArgs e) { await DisplayAlert(""," !","OK"); } } } 

Pestañas




Xamarin.Forms Shell como plantilla raíz puede admitir pestañas inferiores y superiores, así como su combinación:

AppShell.xaml.cs

 <?xml version="1.0" encoding="utf-8" ?> <Shell xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:pages="clr-namespace:HelloShell" x:Class="HelloShell.AppShell"> <TabBar> <Tab Title="MainPage" Icon="xamarin.png"> <ShellContent ContentTemplate="{DataTemplate pages:MainPage}" /> </Tab> <Tab Title="Page1" Icon="xamarin.png"> <ShellContent Title="Main Page" Icon="xamarin.png" ContentTemplate="{DataTemplate pages:MainPage}" /> <ShellContent Title="Page2" Icon="xamarin.png" ContentTemplate="{DataTemplate pages:Page2}" /> </Tab> <Tab IsEnabled="False" Title="Page2" Icon="xamarin.png"> <ShellContent ContentTemplate="{DataTemplate pages:Page2}" /> </Tab> </TabBar> </Shell> 

Como puede ver, esto es bastante simple. Otra ventaja es la carga eficiente de páginas, que le permite inicializar la página solo cuando el usuario accede a ella, lo que acelera significativamente el inicio de la aplicación.

La navegación


Xamarin.Forms proporciona una navegación mejorada basada en URI, lo que le permite ir a cualquier página de la aplicación sin seguir una jerarquía estricta y regresar sin tener que pasar por todas las páginas de la pila de navegación. Para que la navegación funcione, la página debe estar registrada, puede hacerlo en el marcado XAML en FlyoutItem, Tab y ShellContent utilizando la propiedad Ruta

 <Shell ...> <FlyoutItem ... Route="page1"> <Tab ... Route="page2"> <ShellContent ... Route="mainpage" /> <ShellContent ... Route="page3" /> </Tab> <ShellContent ... Route="page4" /> <ShellContent ... Route="page5" /> </FlyoutItem> <ShellContent ... Route="about" /> ... </Shell> 

o en código

 Routing.RegisterRoute("page1", typeof(Page1)); 

la navegación se realiza mediante el comando

 await Shell.Current.GoToAsync("//page2"); 

Como ejemplo, realizamos cambios en los siguientes archivos:

AppShell.xaml

  <TabBar> <Tab Route="main" Title="MainPage" Icon="xamarin.png"> <ShellContent ContentTemplate="{DataTemplate pages:MainPage}" /> </Tab> <Tab Title="Page1" Icon="xamarin.png"> <ShellContent Title="Main Page" Icon="xamarin.png" ContentTemplate="{DataTemplate pages:MainPage}" /> <ShellContent Route="page2" Title="Page2" Icon="xamarin.png" ContentTemplate="{DataTemplate pages:Page2}" /> </Tab> <Tab IsEnabled="False" Title="Page2" Icon="xamarin.png"> <ShellContent ContentTemplate="{DataTemplate pages:Page2}" /> </Tab> </TabBar> 

MainPage.xaml
  <StackLayout VerticalOptions="CenterAndExpand"> <Button Text="Page2" Clicked="ToPage2" /> </StackLayout> 

MainPage.xaml.cs
  public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); } private async void ToPage2(object sender, EventArgs e) { await Shell.Current.GoToAsync("//page2"); } } 

Página2.xaml

  <ContentPage.Content> <StackLayout VerticalOptions="CenterAndExpand"> <Button Text="" Clicked="Back" /> </StackLayout> </ContentPage.Content> 

Page2.xaml.cs

  public partial class Page2 : ContentPage { public Page2() { InitializeComponent(); } private async void Back(object sender, EventArgs e) { await Shell.Current.GoToAsync("//main"); } } 

Buscar


Xamarin.Forms Shell tiene funciones de búsqueda integradas proporcionadas por la clase SearchHandler. Para agregar una función de búsqueda a la página, crearemos una clase PetSearchHandler derivada de SearchHandler y anularemos los métodos OnQueryChanged y OnItemSelected. El método OnQueryChanged se activa cuando un usuario ingresa texto en un campo de búsqueda y toma dos argumentos: oldValue y newValue, que contienen las consultas de búsqueda anteriores y nuevas, respectivamente.

El método SelectedItem se ejecuta cuando el usuario selecciona el resultado de la búsqueda y toma un objeto, en este caso, Animal, como parámetro.

Por ejemplo, crear un modelo animal

Modelos / Animal.cs

  public class Animal { public string Name { get; set; } public string ImageUrl { get; set; } } 

Clase PetData que contendrá una colección de nuestros gatos y perros favoritos

Data / PetData.cs

  public static class PetData { public static IList<Animal> Pets { get; private set; } static PetData() { Pets = new List<Animal>(); Pets.Add(new Animal { Name = "Afghan Hound", ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/6/69/Afghane.jpg" }); Pets.Add(new Animal { Name = "Alpine Dachsbracke", ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/2/23/Alpejski_gończy_krótkonożny_g99.jpg/320px-Alpejski_gończy_krótkonożny_g99.jpg" }); Pets.Add(new Animal { Name = "American Bulldog", ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/5/5e/American_Bulldog_600.jpg" }); Pets.Add(new Animal { Name = "Abyssinian", ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9b/Gustav_chocolate.jpg/168px-Gustav_chocolate.jpg" }); Pets.Add(new Animal { Name = "Arabian Mau", ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/d/d3/Bex_Arabian_Mau.jpg" }); Pets.Add(new Animal { Name = "Bengal", ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Paintedcats_Red_Star_standing.jpg/187px-Paintedcats_Red_Star_standing.jpg" }); Pets.Add(new Animal { Name = "Burmese", ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/0/04/Blissandlucky11.jpg" }); Pets.Add(new Animal { Name = "Cyprus", ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/CyprusShorthair.jpg/320px-CyprusShorthair.jpg" }); Pets.Add(new Animal { Name = "German Rex", ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/c/c7/German_rex_harry_%28cropped%29.jpg" }); } } 

PetSearchHandler.cs

  public class PetSearchHandler : SearchHandler { protected override void OnQueryChanged(string oldValue, string newValue) { base.OnQueryChanged(oldValue, newValue); if (string.IsNullOrWhiteSpace(newValue)) { ItemsSource = null; } else { ItemsSource = PetData.Pets .Where(pet => pet.Name.ToLower().Contains(newValue.ToLower())) .ToList<Animal>(); } } protected override async void OnItemSelected(object item) { base.OnItemSelected(item); var pet = item as Animal; if (pet is null) return; await App.Current.MainPage.DisplayAlert(" ",pet.Name,"ok"); } } 

Agregue una página Mascotas donde establezcamos nuestro PetSearchHandler

 <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" ... x:Class="HelloShell.Pets"> <Shell.SearchHandler> <controls:PetSearchHandler Placeholder="Enter search term" ShowsResults="true" DisplayMemberName="Name" /> </Shell.SearchHandler> <ContentPage.Content> 

Como resultado, deberíamos obtener una página con un campo de búsqueda en la barra de navegación, cuando ingresa una frase de búsqueda, se muestra una lista simple de nombres de mascotas.



Si lo desea, podemos personalizar fácilmente el contenido de la celda de la lista agregando una imagen y varias etiquetas de texto allí:

  <Shell.SearchHandler> <controls:PetSearchHandler Placeholder="Enter search term" ShowsResults="true"> <controls:PetSearchHandler.ItemTemplate> <DataTemplate> <StackLayout Padding="10" Orientation="Horizontal"> <Image Source="{Binding ImageUrl}" Aspect="AspectFill" HeightRequest="40" WidthRequest="40" /> <Label Text="{Binding Name}" FontAttributes="Bold" /> </StackLayout> </DataTemplate> </controls:PetSearchHandler.ItemTemplate> </controls:PetSearchHandler> </Shell.SearchHandler> 



Fuentes en github

Source: https://habr.com/ru/post/470309/


All Articles