Xamarin.Forms Aprofundamento do Início Rápido

Xamarin.Forms No Início Rápido, o aplicativo Notes foi criado. Este artigo analisa o que foi criado para entender os fundamentos de como Xamarin.Forms os aplicativos Shell funcionam.

Introdução ao Visual Studio

O Visual Studio organiza o código em Soluções e Projetos. Uma solução é um contêiner que pode conter um ou mais projetos. Um projeto pode ser um aplicativo, uma biblioteca com suporte, um aplicativo de teste, entre outros. O aplicativo Notes consiste em uma solução contendo três projetos, conforme mostrado na captura de tela a seguir:

Gerenciador de Soluções do Visual Studio

Os projetos são:

  • Notes – esse projeto é o projeto da biblioteca do .NET Standard que contém todos os códigos compartilhados e interfaces do usuário compartilhadas.
  • Notes.Android – esse projeto contém o código específico do Android e é o ponto de entrada para o aplicativo Android.
  • Notes.iOS – esse projeto contém o código específico do iOS e é o ponto de entrada para o aplicativo iOS.

Anatomia de um Xamarin.Forms aplicativo

A captura de tela a seguir mostra o conteúdo do projeto de biblioteca do .NET Standard Notes no Visual Studio:

Conteúdo do projeto do .NET Standard Phoneword

O projeto tem um nó Dependências que contém os nós NuGet e SDK:

  • NuGet – os Xamarin.Formspacotes NuGet , Xamarin.Essentials, Newtonsoft.JSON e sqlite-net-pcl que foram adicionados ao projeto.
  • SDK – o NETStandard.Library metapacote que faz referência ao conjunto completo de pacotes NuGet que definem o .NET Standard.

Introdução ao Visual Studio para Mac

O Visual Studio para Mac segue a prática do Visual Studio de organizar o código em Soluções e Projetos. Uma solução é um contêiner que pode conter um ou mais projetos. Um projeto pode ser um aplicativo, uma biblioteca com suporte, um aplicativo de teste, entre outros. O aplicativo Notes consiste em uma solução contendo três projetos, conforme mostrado na captura de tela a seguir:

Painel de soluções do Visual Studio para Mac

Os projetos são:

  • Notes – esse projeto é o projeto da biblioteca do .NET Standard que contém todos os códigos compartilhados e interfaces do usuário compartilhadas.
  • Notes.Android – esse projeto contém o código específico do Android e é o ponto de entrada para aplicativos Android.
  • Notes.iOS – esse projeto contém o código específico do iOS e é o ponto de entrada para aplicativos iOS.

Anatomia de um Xamarin.Forms aplicativo

A captura de tela a seguir mostra o conteúdo do projeto de biblioteca do .NET Standard Notes no Visual Studio para Mac:

Conteúdo do projeto de biblioteca do .NET Standard Phoneword

O projeto tem um nó Dependências que contém os nós NuGet e SDK:

  • NuGet – os Xamarin.Formspacotes NuGet , Xamarin.Essentials, Newtonsoft.JSON e sqlite-net-pcl que foram adicionados ao projeto.
  • SDK – o NETStandard.Library metapacote que faz referência ao conjunto completo de pacotes NuGet que definem o .NET Standard.

O projeto também consiste em vários arquivos:

  • Data\NoteDatabase.cs – essa classe contém código para criar o banco de dados e ler, gravar e excluir dados do banco de dados.
  • Modelos\Note.cs – essa classe define um modelo de Note cujas instâncias armazenam dados sobre cada observação no aplicativo.
  • Views\AboutPage.xaml – A marcação XAML para a AboutPage classe, que define a interface do usuário para a página sobre.
  • Views\AboutPage.xaml.cs – O code-behind da AboutPage classe, que contém a lógica de negócios que é executada quando o usuário interage com a página.
  • Views\NotesPage.xaml – A marcação XAML para a NotesPage classe, que define a interface do usuário para a página mostrada quando o aplicativo é iniciado.
  • Views\NotesPage.xaml.cs – O code-behind da NotesPage classe, que contém a lógica de negócios que é executada quando o usuário interage com a página.
  • Views\NoteEntryPage.xaml – A marcação XAML para a NoteEntryPage classe, que define a interface do usuário para a página mostrada quando o usuário insere uma anotação.
  • Views\NoteEntryPage.xaml.cs – O code-behind da NoteEntryPage classe, que contém a lógica de negócios que é executada quando o usuário interage com a página.
  • XAML – a marcação XAML para a classe App, que define um dicionário de recursos para o aplicativo.
  • App.xaml.cs – O code-behind da App classe, que é responsável por instanciar o aplicativo Shell e por lidar com eventos de ciclo de vida do aplicativo.
  • AppShell.xaml – A marcação XAML para a AppShell classe, que define a hierarquia visual do aplicativo.
  • AppShell.xaml.cs – O code-behind da AppShell classe, que cria uma rota para que NoteEntryPage ele possa ser navegado programaticamente.
  • AssemblyInfo.cs – esse arquivo contém um atributo de aplicativo sobre o projeto, que é aplicado no nível do assembly.

Para saber mais sobre a anatomia de um aplicativo Xamarin.iOS, consulte Anatomia de um aplicativo Xamarin.iOS. Para saber mais sobre a anatomia de um aplicativo Xamarin.Android, consulte Anatomia de um aplicativo Xamarin.Android.

Arquitetura e conceitos básicos de aplicativo

Um Xamarin.Forms aplicativo é arquitetado da mesma forma que um aplicativo multiplataforma tradicional. O código compartilhado normalmente é colocado em uma biblioteca do .NET Standard e aplicativos específicos de plataforma consomem o código compartilhado. O diagrama a seguir mostra uma visão geral dessa relação para o aplicativo Notes:

Arquitetura do Notes

Para maximizar a reutilização do código de inicialização, Xamarin.Forms os aplicativos têm uma única classe chamada App que é responsável por instanciar o aplicativo em cada plataforma, conforme mostrado no exemplo de código a seguir:

using Xamarin.Forms;

namespace Notes
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
            MainPage = new AppShell();
        }
        // ...
    }
}

Esse código define a MainPage App propriedade da classe para o AppShell objeto. A AppShell classe define a hierarquia visual do aplicativo. O Shell pega essa hierarquia visual e produz a interface do usuário para ela. Para obter mais informações sobre como definir a hierarquia visual do aplicativo, consulte Hierarquia visual do aplicativo.

Além disso, o arquivo AssemblyInfo.cs contém um único atributo de aplicativo, que é aplicado no nível do assembly:

using Xamarin.Forms.Xaml;

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]

O atributo XamlCompilation ativa o compilador XAML para que o XAML seja compilado diretamente em linguagem intermediária. Para saber mais, consulte XAML Compilation (Compilação de XAML).

Inicie o aplicativo em cada plataforma

A forma como o aplicativo é iniciado em cada plataforma é específica para a plataforma.

iOS

Para ativar a página inicial Xamarin.Forms no iOS, o projeto Notes.iOS define a AppDelegate classe que herda da FormsApplicationDelegate classe:

namespace Notes.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());
            return base.FinishedLaunching(app, options);
        }
    }
}

A FinishedLaunching substituição inicializa a Xamarin.Forms estrutura chamando o Init método. Isso faz com que a implementação específica do iOS seja carregada no aplicativo antes que o controlador de Xamarin.Forms exibição raiz seja definido pela chamada para o LoadApplication método.

Android

Para ativar a página inicial Xamarin.Forms no Android, o projeto Notes.Android inclui um código que cria um Activity atributo with MainLauncher , com a atividade herdada da FormsAppCompatActivity classe:

namespace Notes.Droid
{
    [Activity(Label = "Notes",
              Icon = "@mipmap/icon",
              Theme = "@style/MainTheme",
              MainLauncher = true,
              ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
        }
    }
}

A OnCreate substituição inicializa a Xamarin.Forms estrutura chamando o Init método. Isso faz com que a implementação específica do Android seja carregada Xamarin.Forms no aplicativo antes que o Xamarin.Forms aplicativo seja carregado.

Hierarquia visual do aplicativo

Xamarin.Forms Os aplicativos do shell definem a hierarquia visual do aplicativo em uma classe que subclasse a Shell classe. No aplicativo Notas, esta é a Appshell classe:

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:views="clr-namespace:Notes.Views"
       x:Class="Notes.AppShell">
    <TabBar>
        <ShellContent Title="Notes"
                      Icon="icon_feed.png"
                      ContentTemplate="{DataTemplate views:NotesPage}" />
        <ShellContent Title="About"
                      Icon="icon_about.png"
                      ContentTemplate="{DataTemplate views:AboutPage}" />
    </TabBar>
</Shell>

Esse XAML consiste em dois objetos principais:

  • TabBar. O TabBar representa a barra de guias inferior e deve ser usado quando o padrão de navegação do aplicativo usa guias inferiores. O objeto TabBar é um filho do objeto Shell.
  • ShellContent, que representa os ContentPage objetos para cada guia no TabBar. Cada ShellContent objeto é um filho do TabBar objeto.

Esses objetos não representam nenhuma interface do usuário, mas sim a organização da hierarquia visual do aplicativo. O Shell usará esses objetos e produzirá a interface de navegação do conteúdo para o usuário. Portanto, a AppShell classe define duas páginas que podem ser navegadas a partir de guias inferiores. As páginas são criadas sob demanda, em resposta à navegação.

Para obter mais informações sobre aplicativos do Shell, consulte Xamarin.Forms Shell.

Interface do usuário

Existem vários grupos de controle usados para criar a interface do usuário de um Xamarin.Forms aplicativo:

  1. Páginas – Xamarin.Forms as páginas representam telas de aplicativos móveis multiplataforma. O aplicativo Notes usa a classe ContentPage para exibir telas únicas. Para obter mais informações sobre páginas, consulte Xamarin.Forms Páginas.
  2. Exibições – Xamarin.Forms exibições são os controles exibidos na interface do usuário, como rótulos, botões e caixas de entrada de texto. O aplicativo Notes concluído usa as exibições CollectionView, Editor e Button. Para obter mais informações sobre modos de exibição, consulte Xamarin.Forms Modos de exibição.
  3. Layouts – Xamarin.Forms layouts são contêineres usados para compor exibições em estruturas lógicas. O aplicativo Notes usa a classe StackLayout para organizar as exibições em uma pilha vertical e a classe Grid para organizar os botões horizontalmente. Para obter mais informações sobre layouts, consulte Xamarin.Forms Layouts.

No runtime, cada controle será mapeado para seu equivalente nativo, que é o que será renderizado.

Layout

O aplicativo Notes usa o StackLayout para simplificar o desenvolvimento de aplicativos multiplataforma, organizando automaticamente as exibições na tela, independentemente do tamanho da tela. Os elementos filho são posicionados um após o outro, horizontalmente ou verticalmente, na ordem em que foram adicionados. A quantidade de espaço que o StackLayout usará dependerá de como as propriedades HorizontalOptions e VerticalOptions forem definidas, mas por padrão o StackLayout tentará usar a tela inteira.

O código XAML a seguir mostra um exemplo de como usar um StackLayout para definir o layout da NoteEntryPage:

<?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="Notes.Views.NoteEntryPage"
             Title="Note Entry">
    ...    
    <StackLayout Margin="{StaticResource PageMargin}">
        <Editor Placeholder="Enter your note"
                Text="{Binding Text}"
                HeightRequest="100" />
        <Grid>
            ...
        </Grid>
    </StackLayout>    
</ContentPage>

Por padrão, o StackLayout assume uma orientação vertical. No entanto, ele pode ser alterado para uma orientação horizontal definindo a propriedade StackLayout.Orientation como o membro de enumeração StackOrientation.Horizontal.

Observação

O tamanho das exibições pode ser definido por meio das propriedades HeightRequest e WidthRequest.

Para obter mais informações sobre a StackLayout classe, consulte Xamarin.Forms StackLayout.

Respondendo à interação do usuário

Um objeto definido em XAML pode acionar um evento que é processado no arquivo code-behind. O exemplo de código a seguir mostra o método OnSaveButtonClicked no code-behind para a classe NoteEntryPage, que é executada em resposta ao disparo do evento Clicked no botão Salvar.

async void OnSaveButtonClicked(object sender, EventArgs e)
{
    var note = (Note)BindingContext;
    note.Date = DateTime.UtcNow;
    if (!string.IsNullOrWhiteSpace(note.Text))
    {
        await App.Database.SaveNoteAsync(note);
    }
    await Shell.Current.GoToAsync("..");
}

O método OnSaveButtonClicked salva a observação no banco de dados e navega de volta para a página anterior. Para obter mais informações sobre navegação, confira Navegação.

Observação

O arquivo code-behind de uma classe XAML pode acessar um objeto definido em XAML usando o nome atribuído a ele com o atributo x:Name. O valor atribuído a esse atributo tem as mesmas regras que variáveis C#, no sentido de que deve começar com uma letra ou um sublinhado e não conter espaços.

A conexão do botão Salvar para o método OnSaveButtonClicked ocorre na marcação XAML para a classe NoteEntryPage:

<Button Text="Save"
        Clicked="OnSaveButtonClicked" />

Listas

O CollectionView é responsável por exibir uma coleção de itens em uma lista. Por padrão, os itens de lista são exibidos verticalmente e cada item é exibido em uma única linha.

O exemplo de código a seguir mostra o CollectionView da NotesPage:

<CollectionView x:Name="collectionView"
                Margin="{StaticResource PageMargin}"
                SelectionMode="Single"
                SelectionChanged="OnSelectionChanged">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical"
                           ItemSpacing="10" />
    </CollectionView.ItemsLayout>
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <StackLayout>
                <Label Text="{Binding Text}"
                       FontSize="Medium" />
                <Label Text="{Binding Date}"
                       TextColor="{StaticResource TertiaryColor}"
                       FontSize="Small" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

O layout de cada linha no CollectionView é definido dentro do elemento CollectionView.ItemTemplate e usa a associação de dados para exibir todas as observações recuperadas pelo aplicativo. A CollectionView.ItemsSource propriedade é definida como a fonte de dados, em NotesPage.xaml.cs:

protected override async void OnAppearing()
{
    base.OnAppearing();

    collectionView.ItemsSource = await App.Database.GetNotesAsync();
}

Esse código preenche o CollectionView com todas as notas armazenadas no banco de dados e é executado quando a página é exibida.

Quando um item é selecionado no CollectionView, o SelectionChanged evento é acionado. Um manipulador de eventos, chamado OnSelectionChanged, é executado quando o evento é disparado:

async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection != null)
    {
        // ...
    }
}

O SelectionChanged evento pode acessar o objeto que foi associado ao item por meio da e.CurrentSelection propriedade.

Para obter mais informações sobre a CollectionView classe, consulte Xamarin.Forms CollectionView.

A navegação é executada em um aplicativo Shell, especificando um URI para onde navegar. Os URIs de navegação têm três componentes:

  • Uma rota, que define o caminho para o conteúdo que existe como parte da hierarquia visual do Shell.
  • Uma página. As páginas que não existam na hierarquia visual do Shell podem ser enviadas por push para a pilha de navegação de qualquer lugar em um aplicativo Shell. Por exemplo, o NoteEntryPage não é definido na hierarquia visual do Shell, mas pode ser enviado por push para a pilha de navegação conforme necessário.
  • Um ou mais parâmetros de consulta. Parâmetros de consulta são aqueles que podem ser passados para a página de destino durante a navegação.

Um URI de navegação não precisa incluir todos os três componentes, mas quando isso acontece, a estrutura é: //route/page?queryParameters

Observação

As rotas podem ser definidas em elementos na hierarquia visual do Shell por meio da Route propriedade. No entanto, se a Route propriedade não estiver configurada, como no aplicativo Notes, uma rota será gerada no tempo de execução.

Para obter mais informações sobre a navegação do Shell, consulte Xamarin.Forms Navegação do Shell.

Registrar rotas

Para navegar até uma página que não existe na hierarquia visual do Shell, é necessário que ela seja registrada primeiro no sistema de roteamento do Shell. usando o Routing.RegisterRoute método. No aplicativo Notes, isso ocorre no AppShell construtor:

public partial class AppShell : Shell
{
    public AppShell()
    {
        // ...
        Routing.RegisterRoute(nameof(NoteEntryPage), typeof(NoteEntryPage));
    }
}

Neste exemplo, uma rota nomeada NoteEntryPage é registrada em relação ao NoteEntryPage tipo. Essa página pode ser navegada usando a navegação baseada em URI, de qualquer lugar no aplicativo.

Realizar navegação

A navegação é realizada pelo GoToAsync método, que aceita um argumento que representa a rota para a qual navegar:

await Shell.Current.GoToAsync("NoteEntryPage");

Neste exemplo, o NoteEntryPage é navegado para.

Importante

Uma pilha de navegação é criada quando uma página que não está na hierarquia visual do Shell é navegada.

Ao navegar para uma página, os dados podem ser passados para a página como um parâmetro de consulta:

async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection != null)
    {
        // Navigate to the NoteEntryPage, passing the ID as a query parameter.
        Note note = (Note)e.CurrentSelection.FirstOrDefault();
        await Shell.Current.GoToAsync($"{nameof(NoteEntryPage)}?{nameof(NoteEntryPage.ItemId)}={note.ID.ToString()}");
    }
}

Este exemplo recupera o item selecionado no momento e CollectionView navega até o NoteEntryPage, com o valor da propriedade do ID objeto sendo passado como um parâmetro de Note consulta para a NoteEntryPage.ItemId propriedade.

Para receber os dados passados, a classe é decorada NoteEntryPage com o QueryPropertyAttribute

[QueryProperty(nameof(ItemId), nameof(ItemId))]
public partial class NoteEntryPage : ContentPage
{
    public string ItemId
    {
        set
        {
            LoadNote(value);
        }
    }
    // ...
}

O primeiro argumento para o QueryPropertyAttribute especifica que a ItemId propriedade receberá os dados passados, com o segundo argumento especificando o id do parâmetro de consulta. Portanto, o QueryPropertyAttribute no exemplo acima especifica que a ItemId propriedade receberá os dados passados no ItemId parâmetro de consulta do URI na chamada de GoToAsync método. Em seguida, a ItemId propriedade chama o LoadNote método para recuperar a nota do dispositivo.

A navegação para trás é executada especificando ".." como o argumento para o GoToAsync método:

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

Para obter mais informações sobre navegação para trás, consulte Navegação para trás.

Vinculação de dados

A associação de dados é usada para simplificar como um Xamarin.Forms aplicativo exibe e interage com seus dados. Ela estabelece uma conexão entre a interface do usuário e o aplicativo subjacente. A classe BindableObject contém a maior parte da infraestrutura para dar suporte à vinculação de dados.

A vinculação de dados conecta dois objetos, chamados de a origem e o destino. O objeto origem fornece os dados. O objeto destino consumirá (e geralmente exibirá) dados do objeto de origem. Por exemplo, um Editor (objeto alvo) normalmente associará sua propriedade Text a uma propriedade string pública em um objeto de origem. O diagrama a seguir ilustra essa relação de associação:

Associação de dados

O principal benefício da vinculação de dados é que você não precisa se preocupar sobre a sincronização de dados entre suas exibições e a fonte de dados. As alterações no objeto de origem são enviadas automaticamente para o objeto de destino nos bastidores pela estrutura de associação, enquanto as alterações no objeto de destino podem ser opcionalmente enviadas de volta para o objeto de origem.

Estabelecer a vinculação de dados é um processo de duas etapas:

  • A propriedade BindingContext do objeto de destino deve ser definida como a origem.
  • Uma associação deve ser estabelecida entre o destino e a origem. Em XAML, isso é obtido usando a extensão de marcação Binding.

No aplicativo Notes, o alvo de associação é o Editor, que exibe uma observação, enquanto a instância de Note definida como a BindingContext de NoteEntryPage é a origem da associação. Inicialmente, o BindingContext do é definido quando o construtor de NoteEntryPage página é executado:

public NoteEntryPage()
{
    // ...
    BindingContext = new Note();
}

Neste exemplo, a página BindingContext é definida como new Note quando o NoteEntryPage é criado. Isso lida com o cenário de adicionar uma nova nota ao aplicativo.

Além disso, as páginas BindingContext também podem ser definidas quando ocorre a navegação para o NoteEntryPage NotesPage:

[QueryProperty(nameof(ItemId), nameof(ItemId))]
public partial class NoteEntryPage : ContentPage
{
    public string ItemId
    {
        set
        {
            LoadNote(value);
        }

        async void LoadNote(string itemId)
        {
            try
            {
                int id = Convert.ToInt32(itemId);
                // Retrieve the note and set it as the BindingContext of the page.
                Note note = await App.Database.GetNoteAsync(id);
                BindingContext = note;
            }
            catch (Exception)
            {
                Console.WriteLine("Failed to load note.");
            }
        }    
        // ...    
    }
}

Neste exemplo, quando ocorre a navegação de BindingContext página, a página é definida como o objeto selecionado Note depois de ter sido recuperada do banco de dados.

Importante

Embora a propriedade BindingContext de cada objeto de destino possa ser definida individualmente, isso não é necessário. BindingContext é uma propriedade especial que é herdada por todos os seus filhos. Portanto, quando o BindingContext no ContentPage é definido como uma instância de Note, todos os filhos do ContentPage têm o mesmo BindingContext e podem associar-se a propriedades públicas do objeto Note.

O Editor na NoteEntryPage é associado à propriedade Text do objeto Note:

<Editor Placeholder="Enter your note"
        Text="{Binding Text}" />

Uma associação entre a propriedade Editor.Text e a propriedade Text do objeto de origem é estabelecida. As alterações feitas no Editor serão propagadas automaticamente para o objeto Note. Da mesma forma, se forem feitas alterações na Note.Text propriedade, o Xamarin.Forms mecanismo de associação também atualizará o conteúdo do Editor. Isso é conhecido como uma associação bidirecional.

Para obter mais informações sobre a associação de dados, consulte Xamarin.Forms Associação de dados.

Estilo

Xamarin.Forms Os aplicativos geralmente contêm vários elementos visuais que têm uma aparência idêntica. Definir a aparência de cada elemento visual pode ser repetitivo e propenso a erros. Em vez disso, é possível criar estilos para definir a aparência e, em seguida, aplicá-los aos elementos visuais necessários.

A classe Style agrupa uma coleção de valores de propriedade em um objeto que pode ser aplicado a várias instâncias de elementos visuais. Os estilos são armazenados em um ResourceDictionary, seja no nível do aplicativo, no nível da página ou no nível de exibição. Escolher em que local definir um Style afeta o local em que ele pode ser usado:

  • As instâncias Style definidas no nível do aplicativo podem ser aplicadas em todo o aplicativo.
  • As instâncias Style definidas no nível da página podem ser aplicadas a ela e seus filhos.
  • As instâncias Style definidas no nível da exibição podem ser aplicadas a ela e seus filhos.

Importante

Todos os estilos usados em todo o aplicativo são armazenados no dicionário de recursos do aplicativo para evitar duplicação. No entanto, o XAML específico de uma página não deve ser incluído no dicionário de recursos do aplicativo, já que os recursos serão analisados na inicialização do aplicativo, e não quando exigido por uma página. Para obter mais informações, consulte Reduzir o tamanho do dicionário de recursos do aplicativo.

Cada instância de Style contém uma coleção de um ou mais objetos Setter, com cada Setter tendo Property e Value. O Property é o nome da propriedade vinculável do elemento ao qual o estilo é aplicado e o Value é o valor aplicado à propriedade. O exemplo de código a seguir mostra um estilo de NoteEntryPage:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Notes.Views.NoteEntryPage"
             Title="Note Entry">
    <ContentPage.Resources>
        <!-- Implicit styles -->
        <Style TargetType="{x:Type Editor}">
            <Setter Property="BackgroundColor"
                    Value="{StaticResource AppBackgroundColor}" />
        </Style>
        ...
    </ContentPage.Resources>
    ...
</ContentPage>

Esse estilo é aplicado a qualquer instância de Editor na página.

Ao criar um Style, a propriedade TargetType é sempre necessária.

Observação

O estilo de um Xamarin.Forms aplicativo é tradicionalmente realizado usando estilos XAML. No entanto, Xamarin.Forms também suporta o estilo de elementos visuais usando CSS (Folhas de Estilos em Cascata). Para obter mais informações, consulte Estilizar aplicativos usando CSS (Folhas de Xamarin.Forms Estilos em Cascata).

Para obter mais informações sobre estilos XAML, consulte Estilizando Xamarin.Forms aplicativos usando estilos XAML.

Teste e implantação

Tanto o Visual Studio para Mac quanto o Visual Studio oferecem várias opções para testar e implantar um aplicativo. Depurar aplicativos é uma parte comum do ciclo de vida de desenvolvimento de aplicativo e ajuda a diagnosticar problemas de código. Para saber mais, consulte Definir um ponto de interrupção, Percorrer o código e Enviar as informações para a janela de log.

Simuladores são um bom lugar para começar a implantar e testar um aplicativo e eles apresentam recursos úteis para testar aplicativos. No entanto, os usuários não consumirão o aplicativo final em um simulador, assim, os aplicativos devem ser testados em dispositivos reais antecipadamente e com frequência. Para saber mais sobre o provisionamento de dispositivo iOS, consulte Provisionamento de Dispositivo. Para saber mais sobre o provisionamento de dispositivo Android, consulte Configurar o dispositivo para desenvolvimento.

Próximas etapas

Este mergulho profundo examinou os fundamentos do desenvolvimento de aplicativos usando Xamarin.Forms o Shell. As próximas etapas sugeridas incluem ler sobre as seguintes funcionalidades:

  • Xamarin.Forms A Shell reduz a complexidade do desenvolvimento de aplicativos móveis, fornecendo os recursos fundamentais que a maioria dos aplicativos móveis exige. Para obter mais informações, consulte Xamarin.Forms Shell.
  • Existem vários grupos de controle usados para criar a interface do usuário de um Xamarin.Forms aplicativo. Para obter mais informações, confira Referência de controles.
  • A associação de dados é uma técnica para vincular propriedades de dois objetos para que as alterações em uma propriedade sejam automaticamente refletidas na outra propriedade. Para obter mais informações, confira Associação de dados.
  • Xamarin.Forms Fornece várias experiências de navegação de página, dependendo do tipo de página que está sendo usado. Para obter mais informações, veja Navegação.
  • Estilos ajudam a reduzir as marcações repetitivas e permitem que a aparência de aplicativos seja alterada com mais facilidade. Para obter mais informações, consulte Estilizando Xamarin.Forms aplicativos.
  • Os modelos de dados fornecem a capacidade de definir a apresentação de dados em exibições com suporte. Para saber mais, veja Modelos de dados.
  • Efeitos também permitem que os controles nativos em cada plataforma sejam personalizados. Os efeitos são criados em projetos específicos da plataforma por meio da subclasse da PlatformEffect classe e são consumidos anexando-os a um controle apropriado Xamarin.Forms . Para obter mais informações, veja Efeitos.
  • Cada página, layout e exibição é renderizado diferentemente em cada plataforma usando uma classe Renderer, que por sua vez cria um controle nativo, organiza sua disposição na tela e adiciona o comportamento especificado no código compartilhado. Os desenvolvedores podem implementar suas próprias classes Renderer personalizadas para personalizar a aparência e/ou o comportamento de um controle. Para obter mais informações, veja Renderizadores personalizados.
  • O código compartilhado pode acessar a funcionalidade nativa por meio da classe DependencyService. Para obter mais informações, consulte Acessar recursos nativos com DependencyService.

Encontre mais vídeos sobre o Xamarin no Channel 9 e no YouTube.