Neste artigo vou apresentar o novo recurso Shapes do Xamarin Forms 4.7. |
Para realizar desenhos em aplicações Xamarin Forms você tinha que usar uma biblioteca de terceiros como a SkiaSharp.
Tinha, pois a partir da versão 4.7 do Xamarin Forms, temos disponível o recurso Shapes.
Um
Shape é um tipo
de View que permite desenhar uma forma na tela. Os objetos Shape podem ser
usados nas classes de layout e na maioria dos controles, visto que a classe
Shape deriva da classe View.
O novo recurso Shapes está disponível no namespace
Xamarin.Forms.Shapes no iOS, Android, macOS, na
Plataforma Universal do Windows (UWP) e na Windows Presentation Foundation
(WPF).
Atualmente, o Xamarin.Forms Shapes esta na fase dita experimental e pode ser usado definindo a configuração da flag Shapes_Experimental que deve ser adicionada conforme mostra o código abaixo nas classes AppDelegate no iOS, e, MainActivity no Android, antes da chamada de Forms.Init:
global::Xamarin.Forms.Forms.SetFlags("Shapes_Experimental"); |
A classe Shape define as seguintes propriedades:
Todas elas suportam objetos BindableProperty podendo assim serem usadas no Data Binding.
A seguir temos os diferentes objetos que derivam da classe Shape:
Podemos ainda aplicar animações que conectam elementos comuns de uma página a outra. Para usar este recurso basta fazer o seguinte :
Configura a documentação em : https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/shapes/
Os objetos Shape têm uma propriedade Aspect, do tipo Stretch que determina como o conteúdo de um objeto Shape é esticado para preencher o espaço de layout do objeto Shape.
O espaço de layout de um objeto Shape é a quantidade de espaço que o Shape é alocado pelo sistema de layout do Xamarin.Forms, devido a uma configuração explícita WidthRequest e HeightRequest ou pelas configurações HorizontalOptions e VerticalOptions.
A enumeração Stretch define os seguintes membros:
Os objetos Color são usados para pintar o traçado e o preenchimento da forma. No exemplo o traçado (Stroke) esta sendo pintado de vermelho e o preenchimento (Fill) de azul escuro:
<Ellipse Fill="DarkBlue"
Stroke="Red"
StrokeThickness="4"
WidthRequest="150"
HeightRequest="50"
HorizontalOptions="Start" />
|
'Bora' pra prática...
Recursos usados:
Criando o projeto Xamarin Forms
Vamos criar um novo projeto Xamarin Forms no VS 2019 Community com o nome XF_Shapes1.
Nota: Verifique se você precisa atualizar as versões do Xamarin Forms e do Xamarin.Essentials
Você pode ver como criar um projeto no Xamarin Forms neste link: Criar Projeto Xamarin Forms
Crie uma pasta Views no projeto e nesta pasta inclua seis Content Pages : RectanglePage.xaml, EllipsePage.xaml, LinePage.xaml, PolylinePage.xaml, PolygonPage.xaml e PathPage.xaml
Abra o arquivo App.xaml.cs e altere o código do construtor da classe App:
...
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage()); } ... |
A seguir abra o arquivo MainPage.xaml e inclua o código abaixo:
<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="XF_Shapes1.MainPage">
<StackLayout>
<StackLayout HorizontalOptions="Center" VerticalOptions="Center">
<Button x:Name="btnShape1" Text="Rectangle" Clicked="btnShape1_Clicked"/>
<Button x:Name="btnShape2" Text="Ellipse" Clicked="btnShape2_Clicked"/>
<Button x:Name="btnShape3" Text="Line" Clicked="btnShape3_Clicked"/>
<Button x:Name="btnShape4" Text="PolyLine" Clicked="btnShape4_Clicked"/>
<Button x:Name="btnShape5" Text="Polygon" Clicked="btnShape5_Clicked"/>
<Button x:Name="btnShape6" Text="Path" Clicked="btnShape6_Clicked"/>
</StackLayout>
</StackLayout>
</ContentPage>
|
Aqui apenas criamos os botões na página principal para acionar os tipos figuras que iremos tratar.
E no arquivo MainPage.xaml.cs o código para os eventos Click de cada Button:
using System;
using System.ComponentModel;
using Xamarin.Forms;
using XF_Shapes1.Views;
namespace XF_Shapes1
{
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void btnShape1_Clicked(object sender, EventArgs e)
{
App.Current.MainPage.Navigation.PushAsync(new RectanglePage());
}
private void btnShape2_Clicked(object sender, EventArgs e)
{
App.Current.MainPage.Navigation.PushAsync(new EllipsePage());
}
private void btnShape3_Clicked(object sender, EventArgs e)
{
App.Current.MainPage.Navigation.PushAsync(new LinePage());
}
private void btnShape4_Clicked(object sender, EventArgs e)
{
App.Current.MainPage.Navigation.PushAsync(new PolylinePage());
}
private void btnShape5_Clicked(object sender, EventArgs e)
{
App.Current.MainPage.Navigation.PushAsync(new PolygonPage());
}
private void btnShape6_Clicked(object sender, EventArgs e)
{
App.Current.MainPage.Navigation.PushAsync(new PathPage());
}
}
}
|
Vejamos agora o tratamento básico para cada uma das formas que derivam de Shapes.
Nota: Para simplificar estou mostrando apenas o código que efetivamente desenha a figura.
1- RectanglePage.xaml
É uma forma com quatro lados cujos lados opostos são os mesmos. Para criar um retângulo básico, as propriedades WidthRequest, HeightRequest e Fill devem ser especificadas.
A classe Rectangle possui as propriedades:
Para dar um
contorno ao retângulo, defina sua propriedade Stroke
como Color.
A propriedade StrokeThickness especifica a
espessura do contorno do retângulo.
Para fornecer cantos arredondados ao retângulo, defina suas propriedades
RadiusX e RadiusY.
... <StackLayout Padding="10">
<Rectangle
Fill="Red"
WidthRequest="150"
HeightRequest="100"
HorizontalOptions="Center" />
<Rectangle
Fill="White"
Stroke ="Black"
WidthRequest="150"
HeightRequest="150"
HorizontalOptions="Center" />
<Rectangle Fill="DarkBlue"
Stroke="Red"
StrokeThickness="4"
StrokeDashArray="1,1"
StrokeDashOffset="6"
WidthRequest="150"
HeightRequest="50"
HorizontalOptions="Center" />
<Rectangle Fill="Yellow"
Stroke="Black"
StrokeThickness="3"
RadiusX="50"
RadiusY="10"
WidthRequest="150"
HeightRequest="100"
HorizontalOptions="Center" />
</StackLayout>
... |
|
2- EllipsePage.xaml
Uma Elipse é um tipo de seção cônica.
Para desenhar uma
elipse, crie um objeto Ellipse e defina suas
propriedades WidthRequest e HeightRequest.
Para pintar o interior da elipse, defina sua propriedade
Fill como Color.
Para dar um contorno à elipse, defina sua propriedade
Stroke como uma Cor.
A propriedade StrokeThickness especifica a
espessura do contorno da elipse.
...
<StackLayout Margin="20">
<Label Text="Elipse preenchida" />
<Ellipse Fill="Red"
WidthRequest="100"
HeightRequest="50"
HorizontalOptions="Center" />
<Label Text="Circulo" />
<Ellipse Stroke="Red"
StrokeThickness="4"
WidthRequest="100"
HeightRequest="100"
HorizontalOptions="Center" />
<Label Text="Ellipse com stroke" />
<Ellipse Stroke="Black"
StrokeThickness="4"
WidthRequest="100"
HeightRequest="50"
HorizontalOptions="Center" />
<Label Text="Filled ellipse com stroke" />
<Ellipse Fill="Yellow"
Stroke="Red"
StrokeThickness="4"
WidthRequest="100"
HeightRequest="50"
HorizontalOptions="Center" />
<Label Text="ellipse com dashed stroke" />
<Ellipse Fill="Blue"
Stroke="Red"
StrokeThickness="4"
StrokeDashArray="1,1"
StrokeDashOffset="6"
WidthRequest="150"
HeightRequest="50"
HorizontalOptions="Center" />
</StackLayout>
...
|
|
3- LinePage.xaml
A classe Line pode ser usada para desenhar linhas e define as seguintes propriedades:
Para desenhar uma linha, crie um objeto Line e defina suas propriedades X1 e Y1 como ponto inicial e suas propriedades X2 e Y como ponto final. Além disso, defina sua propriedade Stroke como Color, porque uma linha sem traço é invisível.
...
<ScrollView>
<StackLayout Margin="20" Padding="10">
<Label Text="Line" />
<Line X1="40"
Y1="0"
X2="0"
Y2="120"
Stroke="Red" />
<Label Text="Line with stroke" />
<Line X1="40"
Y1="0"
X2="0"
Y2="120"
Stroke="DarkBlue"
StrokeThickness="4" />
<Label Text="Dashed line" />
<Line X1="40"
Y1="0"
X2="0"
Y2="120"
Stroke="DarkBlue"
StrokeDashArray="1,1"
StrokeDashOffset="6" />
<Label Text="LineCap: Flat" />
<Line X1="0"
Y1="20"
X2="300"
Y2="20"
StrokeLineCap="Flat"
Stroke="Red"
StrokeThickness="12" />
<Label Text="LineCap: Square" />
<Line X1="0"
Y1="20"
X2="300"
Y2="20"
StrokeLineCap="Square"
Stroke="Green"
StrokeThickness="12" />
<Label Text="LineCap: Round" />
<Line X1="0"
Y1="20"
X2="300"
Y2="20"
StrokeLineCap="Round"
Stroke="Black"
StrokeThickness="12" />
</StackLayout>
</ScrollView>
...
|
|
4- PolylinePage.xaml
A classe Polyline deriva da classe Shape e pode ser usada para desenhar uma série de linhas retas conectadas. Uma polilinha é semelhante a um polígono, exceto que o último ponto de uma polilinha não está conectado ao primeiro ponto. Esta classe define as seguintes propriedades:
O tipo PointsCollection é um objeto ObservableCollection de Point.
A estrutura Point define propriedades X e Y, do tipo double, que representam um par de coordenadas x e y no espaço 2D. Portanto, a propriedade Points deve ser definida como uma lista de pares de coordenadas e coordenadas y que descrevem os pontos de vértice da polilinha, delimitados por uma única vírgula e/ou um ou mais espaços. Por exemplo, "40,10 70,80" e "40 10, 70 80" são válidos.
...
<ScrollView>
<StackLayout Margin="20" Padding="10">
<Label Text="Polyline" />
<Polyline Points="0,0 10,30, 15,0 18,60 23,30 35,30 40,0 43,60 48,30 100,30"
Stroke="Red" />
<Label Text="Polyline with dashed stroke" />
<Polyline Points="0,0 10,30, 15,0 18,60 23,30 35,30 40,0 43,60 48,30 100,30"
Stroke="Red"
StrokeThickness="2"
StrokeDashArray="1,1"
StrokeDashOffset="6" />
<Label Text="EvenOdd polyline" />
<!-- FillRule não precisa ser definido pois EvenOdd é o padrão default. -->
<Polyline Points="0 48, 0 144, 96 150, 100 0, 192 0, 192 96, 50 96, 48 192, 150 200 144 48"
Fill="Blue"
Stroke="Red"
StrokeThickness="3" />
<Label Text="NonZero polyline" />
<Polyline Points="0 48, 0 144, 96 150, 100 0, 192 0, 192 96, 50 96, 48 192, 150 200 144 48"
Fill="Black"
FillRule="Nonzero"
Stroke="Yellow"
StrokeThickness="3" />
<Label Text="LineJoin: Miter" />
<!-- StrokeLineJoin não precisa ser definida pois Miter é o padrão. -->
<Polyline Points="20 20,250 50,20 120"
Stroke="Black"
StrokeThickness="20" />
<Label Text="LineJoin: Bevel" />
<Polyline Points="20 20,250 50,20 120"
Stroke="DarkBlue"
StrokeThickness="20"
StrokeLineJoin="Bevel" />
<Label Text="LineJoin: Round" />
<Polyline Points="20 20,250 50,20 120"
Stroke="Red"
StrokeThickness="20"
StrokeLineJoin="Round" />
</StackLayout>
</ScrollView>
...
|
Abaixo temos o resultado:
Na próxima parte do artigo vamos continuar a apresentar as demais formas derivadas de Shape.
Pegue o código do projeto compartilhado aqui : XF_Shapes1.zip
(Porque a vida
foi manifestada, e nós a vimos, e testificamos dela, e vos anunciamos a vida
eterna, que estava com o Pai, e nos foi manifestada);
1 João 1:2
Referências:
NET - Apresentando o padrão Model-View-ViewModel
Xamarin Forms - MVVM - Macoratti.net
NET - O padrão MVVM (Model-View-ViewModel) revisitado
Xamarin Forms - MVVM - A interface ICommand
Padrão de Projeto - Aprendendo o padrão MVVM ...