Este artigo apresenta a view BoxView e mostra como simular um relógio analógico em uma aplicação Xamarin Forms. |
A view
BoxView processa um retângulo simples de uma largura, altura e cor
especificadas. Você pode usar a BoxView para decoração, gráficos rudimentares e
para interação com o usuário através do toque.
Como o Xamarin.Forms não possui um sistema de gráficos vetoriais incorporado, a
BoxView ajuda a compensar essa deficiência. Assim, uma BoxView pode ser dimensionada para se assemelhar a
uma linha de largura e espessura específica e, em seguida, girada por qualquer
ângulo usando a propriedade Rotation. (A view BoxView é mais usada
para gráficos simples para gráficos mais sofisticados veja o
SkiaSharp))
Ao usar a
view BoxView definimos as seguintes propriedades:
- Color - para definir a cor.
- WidthRequest para definir a largura do BoxView em unidades
independentes do dispositivo.
- HeightRequest para definir a altura do BoxView.
A propriedade Color é de tipo Color e pode
ser configurada para qualquer valor de Color, incluindo os 141 campos estáticos
somente leitura de cores com nomes variando alfabeticamente de AliceBlue para
YellowGreen.
As
propriedades WidthRequest e HeightRequest apenas
desempenham uma função se o BoxView não for restringido no layout. Este é o caso
quando o contêiner de layout precisa conhecer o tamanho o elemento filho, por
exemplo, quando o BoxView é um filho de uma célula de tamanho automático no
layout de um Grid. Um BoxView também não é compatível quando suas propriedades
HorizontalOptions e VerticalOptions são definidas
para valores diferentes de LayoutOptions.Fill. Se o
BoxView não for restringido, mas as propriedades
WidthRequest e HeightRequest não estão definidas, a largura ou a altura
estão configuradas para valores padrão de 40 unidades, ou cerca de 1/4 de
polegada nos dispositivos móveis.
As propriedades WidthRequest e
HeightRequest são ignoradas se o BoxView for
restringido no layout, caso em que o contêiner de layout impõe seu próprio
tamanho no BoxView.
Uma BoxView pode ser restringida em uma dimensão e não ter restrições na outra.
Por exemplo, se a BoxView for filho de um StackLayout vertical, a dimensão
vertical do BoxView não esta restrita e sua dimensão horizontal geralmente esta
restringida.
A seguir temos uma página onde definimos 4 views BoxView definindo as propriedades: Color, WidthRequest, HeighRequest e Opacity
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XF_Analogico.BoxViewPage"
BackgroundColor="White">
<StackLayout>
<StackLayout Padding="20">
<BoxView Color="Black" WidthRequest="150" HeightRequest="150"
VerticalOptions="Center"
HorizontalOptions="Center" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<BoxView Color="Red" WidthRequest="50" HeightRequest="50" Opacity="0.5" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<BoxView Color="Yellow" WidthRequest="50" HeightRequest="25" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<BoxView Color="Green" WidthRequest="25" HeightRequest="50" />
</StackLayout>
</StackLayout>
</ContentPage>
|
Neste artigo vamos usar a view BoxView para definir um desenho simulando um relógio análogico.
Nota: O exemplo deste artigo foi baseado no original em : http://www.c-sharpcorner.com/article/how-to-box-view-clock-in-xamarin-forms/
Recursos usados:
Visual Studio Community 2017 ou Xamarin Studio
Criando o projeto no Visual Studio 2017 Community
Abra o Visual Studio Community 2017 e clique em New Project;
Selecione Visual C#, o template Cross-Plataform e a seguir Cross-Platform App (Xamarin.Forms);
Informe o nome XF_Analogico e clique no botão OK;
Selecione as plataformas desejadas: Android, iOS e UWP, marque o item Xamarin.Forms e a seguir escolha .NET Standard e clique no botão OK.
Nota: A partira da versão 15.5 do Visual Studio o template PCL foi substituito pelo .NET Standard.
Usando a view BoxView
Abra a página MainPage.xaml e inclua o código abaixo nesta página:
<?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:XF_Analogico"
x:Class="XF_Analogico.MainPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="IOS" Value="0, 20, 0, 0" />
</OnPlatform>
</ContentPage.Padding>
<AbsoluteLayout x:Name="absoluteLayout"
SizeChanged="OnAbsoluteLayoutSizeChanged">
<BoxView x:Name="ponteiroHora"
Color="Black" />
<BoxView x:Name="ponteiroMinuto"
Color="Black" />
<BoxView x:Name="ponteiroSegundo"
Color="Black" />
</AbsoluteLayout>
</ContentPage>
|
Usamos no código XAML acima o leiaute AbsoluteLayout e definimos 3 BoxViews representando cada um dos ponteiros do relógio.
Agora vamos definir o código para desenhar os ponteiros e as marcações dos segundos.
Abra o arquivo MainPage.xaml.cs e inclua o código abaixo:
using System;
using Xamarin.Forms;
namespace XF_Analogico
{
public partial class MainPage : ContentPage
{
struct PonteiroParametros
{
public PonteiroParametros(double largura, double altura, double offset) : this()
{
Width = largura;
Height = altura;
Offset = offset;
}
public double Width { private set; get; } // fração do raio
public double Height { private set; get; } //
public double Offset { private set; get; } // relativo ao centro
}
static readonly PonteiroParametros segundoParametros = new PonteiroParametros(0.02, 1.1, 0.85);
static readonly PonteiroParametros minutoParametros = new PonteiroParametros(0.05, 0.8, 0.9);
static readonly PonteiroParametros horaParametros = new PonteiroParametros(0.125, 0.65, 0.9);
BoxView[] tickMarcas = new BoxView[60];
public MainPage()
{
InitializeComponent();
// Cria um marca de tick (para ser dimensionada e posicionada mais tarde).
for (int i = 0; i < tickMarcas.Length; i++)
{
tickMarcas[i] = new BoxView { Color = Color.Black };
absoluteLayout.Children.Add(tickMarcas[i]);
}
Device.StartTimer(TimeSpan.FromSeconds(1.0 / 60), OnTimerTick);
}
void OnAbsoluteLayoutSizeChanged(object sender, EventArgs args)
{
// Pega o centro e o raio do AbsoluteLayout.
Point centro = new Point(absoluteLayout.Width / 2, absoluteLayout.Height / 2);
double raio = 0.45 * Math.Min(absoluteLayout.Width, absoluteLayout.Height);
// Posicao, tamanho, e rotação 60 ticks
for (int index = 0; index < tickMarcas.Length; index++)
{
double tamanho = raio / (index % 5 == 0 ? 15 : 30);
double radians = index * 2 * Math.PI / tickMarcas.Length;
double x = centro.X + raio * Math.Sin(radians) - tamanho / 2;
double y = centro.Y - raio * Math.Cos(radians) - tamanho / 2;
AbsoluteLayout.SetLayoutBounds(tickMarcas[index], new Rectangle(x, y, tamanho, tamanho));
tickMarcas[index].Rotation = 180 * radians / Math.PI;
}
// Posicao e tamanho
LayoutPonteiro(ponteiroSegundo, segundoParametros, centro, raio);
LayoutPonteiro(ponteiroMinuto, minutoParametros, centro, raio);
LayoutPonteiro(ponteiroHora, horaParametros, centro, raio);
}
void LayoutPonteiro(BoxView boxView, PonteiroParametros ponteiroParametros, Point centro, double raio)
{
double largura = ponteiroParametros.Width * raio;
double altura = ponteiroParametros.Height * raio;
double offset = ponteiroParametros.Offset;
AbsoluteLayout.SetLayoutBounds(boxView,
new Rectangle(centro.X - 0.5 * largura,
centro.Y - offset * altura,
largura, altura));
// Atribui a propriedade AnchorY para rotação
boxView.AnchorY = ponteiroParametros.Offset;
}
bool OnTimerTick()
{
// Define o angulo de rotação para hora e minutos
DateTime dataHora = DateTime.Now;
ponteiroHora.Rotation = 30 * (dataHora.Hour % 12) + 0.5 * dataHora.Minute;
ponteiroMinuto.Rotation = 6 * dataHora.Minute + 0.1 * dataHora.Second;
// Faz uma animação para segundo
double t = dataHora.Millisecond / 1000.0;
if (t < 0.5)
{
t = 0.5 * Easing.SpringIn.Ease(t / 0.5);
}
else
{
t = 0.5 * (1 + Easing.SpringOut.Ease((t - 0.5) / 0.5));
}
ponteiroSegundo.Rotation = 6 * (dataHora.Second + t);
return true;
}
}
}
|
Definimos uma Struct para cada ponteiro e um array de BoxView com 60 elementos representando os segundos do relógio; depois acionamos a thread Device.StartTimer.
Executando o projeto iremos obter:
Pegue o projeto completo aqui : XF_Analogico.zip (sem as referências)
"E esta é a mensagem que dele ouvimos, e
vos anunciamos: que Deus é luz, e não há nele trevas nenhumas. "
1 João 1:5
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET
Xamarim - Desenvolvimento Multiplataforma com C# ... - Macoratti.net
Xamarin.Forms - Olá Mundo - Criando sua primeira ... - Macoratti.net
Xamarin.Forms - Olá Mundo - Anatomia da aplicação - Macoratti.net
https://developer.xamarin.com/api/type/Android.Widget.ListView/
https://developer.xamarin.com/guides/xamarin-forms/user-interface/boxview/