Abril de 2019

Volume 34 – Número 4

[Xamarin]

Novidades no Xamarin.Forms 4.0

Por Alessandro Del Del

Durante a conferência Connect(), em novembro de 2018, a Microsoft divulgou a primeira versão prévia pública do Xamarin.Forms 4.0, a última versão da tecnologia de desenvolvimento popular que torna simples criar interfaces do usuário compartilhadas entre diferentes sistemas operacionais, incluindo Windows 10, iOS e Android. Versões prévias atualizadas vieram em seguida, dando aos desenvolvedores uma visão mais detalhada do progresso dessa importante versão principal. Os novos recursos mais importantes que tornam o Xamarin.Forms 4.0 incrível podem ser resumidos conforme mostrado a seguir.

O Shell é um contêiner de aplicativos que fornece os recursos mais comuns dos quais a interface do usuário necessita. Ele representa um único lugar para descrever a estrutura visual de um aplicativo e inclui uma interface do usuário comum para navegação por páginas; um serviço de navegação com vinculação profunda; e um manipulador de pesquisa integrado. Por enquanto, o Shell será disponibilizado somente para iOS e Android.

CollectionView é um controle totalmente novo criado para trabalhar com listas de dados de uma maneira mais eficiente e com grande desempenho. Ele também é a base da versão atualizada do controle CarouselView.

Visual é o nome da nova propriedade que algumas exibições podem usar para renderizar controles com base em um determinado design, facilitando a criação de interfaces do usuário consistentes entre plataformas diferentes.

Você encontrará uma discussão completa sobre o recurso Shell na Edição Especial da Connect(); (msdn.com/magazine/mt848639); portanto, não o abordarei aqui. Em vez disso, me concentrarei no CollectionView, CarouselView, Visual e em outras diversas melhorias feitas na base de código existente. Também darei uma olhada rápida em alguns dos novos recursos incluídos no Visual Studio 2019 Preview 2 para Xamarin.Forms. Lembre-se de que os bits descritos neste artigo ainda estão na versão prévia e podem estar sujeitos a alterações.

Criar e configurar um projeto

Para trabalhar com a versão prévia atual do Xamarin.Forms 4.0, você primeiro precisa criar um projeto de aplicativo móvel (Xamarin.Forms) no Visual Studio 2017, como faria normalmente. Selecione as plataformas iOS e Android e a estratégia de compartilhamento de código do .NET Standard. Quando o novo projeto estiver pronto, com o gerenciador de pacotes NuGet, atualize a biblioteca do Xamarin.Forms para a última versão prévia disponível (no momento da redação deste artigo, era a versão 4.0.0.94569-pre3). Quando você instalar essa versão prévia, o NuGet também adicionará o pacote Xamarin.iOS.MaterialComponents ao projeto da plataforma iOS, como será discutido mais adiante, quando falamos sobre a propriedade Visual.

A última etapa consiste em habilitar todos os recursos experimentais na versão prévia do Xamarin.Forms 4.0 dentro do arquivo MainActivity.cs para Android e do arquivo AppDelegate.cs para iOS. Em ambos os arquivos, adicione a seguinte linha de código antes da invocação do método Xamarin.Forms.Forms.Init:

global::Xamarin.Forms.Forms.SetFlags("Shell_Experimental", "Visual_Experimental",
  "CollectionView_Experimental");

Para testar o recurso Shell, você deve adicionar o sinalizador Shell_Experimental; caso contrário, ele será opcional nos próximos tópicos.

Trabalhando com dados: o controle CollectionView

O Xamarin.Forms 4.0 introduz um controle totalmente novo chamado CollectionView, que você pode usar para exibir e editar listas de dados. Do ponto de vista arquitetônico, o CollectionView tem alguns benefícios principais. Primeiro, ao contrário do ListView, os modelos de dados não dependem mais das exibições de Célula, o que simplifica a árvore visual. Consequentemente, e como segundo benefício, você codifica objetos CollectionView usando a mesma abordagem familiar, com base em XAML, mas com código muito mais simples. Além disso, o controle CollectionView simplifica o gerenciamento do layout de suas listas, oferecendo suporte a layouts horizontais e exibições de grade. Vamos começar criando alguns dados de exemplo que serão exibidos dentro de um controle CollectionView. No projeto do .NET Standard, adicione a classe mostrada na Figura 1, que representa a definição simplificada de um produto.

Figura 1 - Implementação simplificada de uma classe de produtos

public class Product : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;
  private void OnPropertyChanged([CallerMemberName] string propertyName = null)
  {
    PropertyChanged?.Invoke(this,
      new PropertyChangedEventArgs(propertyName));
  }
  private int _productQuantity;
  private string _productName;
  private string _productImage;
  public int ProductQuantity
  {
    get
    {
      return _productQuantity;
    }
    set
    {
      _productQuantity = value;
      OnPropertyChanged();
    }
  }
  public string ProductName
  {
    get
    {
      return _productName;
    }
    set
    {
      _productName = value;
      OnPropertyChanged();
    }
  }
  public string ProductImage
  {
    get
    {
      return _productImage;
    }
    set
    {
      _productImage = value;
      OnPropertyChanged();
    }
  }
}

Observe como a classe Product implementa a interface INotifyPropertyChanged para dar suporte à notificação de alteração, caso você decida tornar editável uma instância do produto. A próxima etapa é definir um modelo de exibição que exponha as informações do produto, que serão associação de dados com a interface do usuário. Isso é mostrado na Figura 2.

Figura 2 - A classe ProductViewModel expõe informações de dados na interface do usuário

public class ProductViewModel
{
  public ObservableCollection<Product> Products { get; set; }
  public ProductViewModel()
  {
    // Sample products
    this.Products = new ObservableCollection<Product>();
    this.Products.Add(new Product { ProductQuantity = 50, ProductName = "Cheese",
                                    ProductImage = "Cheese.png" });
    this.Products.Add(new Product { ProductQuantity = 10, ProductName = "Water",
                                    ProductImage = "Water.png" });
    this.Products.Add(new Product { ProductQuantity = 6, ProductName = "Bread",
                                    ProductImage = "Bread.png" });
    this.Products.Add(new Product { ProductQuantity = 40, ProductName = "Tomatoes",
                                    ProductImage = "Tomato.png" });
  }
}

Em um cenário real, os dados poderiam ter como origem um banco de dados ou um serviço Web; mas, neste caso, posso criar alguns produtos diretamente no código para fins de demonstração. Os arquivos de imagem usados na Figura 2 podem ser encontrados no código complementar do artigo. No arquivo MainPage.xaml do seu projeto, você pode declarar um controle CollectionView para exibir os dados. Os principais pontos são atribuir à propriedade ItemsSource a coleção que você deseja exibir e definir um modelo de dados para cada item da lista. A Figura 3 oferece um exemplo.

Figura 3 - Declaração de CollectionView para exibir dados

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="https://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XF4_WhatsNew"
             x:Class="XF4_WhatsNew.MainPage">
  <StackLayout>
    <CollectionView x:Name="ProductList" ItemsSource="{Binding Products}">
      <CollectionView.ItemTemplate>
        <DataTemplate>
          <Grid>
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="24"/>
              <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Image Source="{Binding ProductImage}" HeightRequest="22" />
            <StackLayout Grid.Column="1" Orientation="Vertical" Spacing="5">
              <Label Text="{Binding ProductName}" FontSize="Medium"
                TextColor="Blue"/>
              <Label Text="{Binding ProductQuantity}" FontSize="Small"
                TextColor="Black"/>
            </StackLayout>
          </Grid>
        </DataTemplate>
      </CollectionView.ItemTemplate>
    </CollectionView>
  </StackLayout>
</ContentPage>

Declarar CollectionView e atribuir à sua propriedade ItemTemplate um objeto DataTemplate no XAML, funciona da mesma maneira que com o controle ListView. A diferença importante é que você não precisa mais lidar com exibições de célula. Em seguida, crie uma instância da classe ProductViewModel e atribua-a à propriedade BindingContext da página, para que a associação de dados funcione, como no código a seguir, a ser escrito no arquivo MainPage.xaml.cs:

public partial class MainPage : ContentPage
{
  private ProductViewModel ViewModel { get; set; }
  public MainPage()
  {
    InitializeComponent();
    this.ViewModel = new ProductViewModel();
    this.BindingContext = this.ViewModel;
  }
}

Se você executar esse código, verá um resultado semelhante ao da Figura 4.

Exibição de listas de dados com CollectionView
Figura 4 - Exibição de listas de dados com CollectionView

Como verá, CollectionView oferece outras propriedades interessantes para implementar layouts diferentes e processar a seleção de itens.

Orientação e layout Se você tem experiência com o controle ListView no Xamarin.Forms, já sabe que não há uma opção interna para definir a orientação como horizontal. Para isso, é preciso usar renderizadores personalizados, o que aumenta a complexidade do código. Da mesma maneira, não há uma opção interna para alterar o layout de uma exibição de lista para uma exibição de grade. O controle CollectionView, no entanto, torna extremamente simples a definição de opções de layout por meio da propriedade ItemsLayout, à qual se pode atribuir propriedades da classe ListItemsLayout, como VerticalList e HorizontalList. Por padrão, atribui-se ListItemsLayout.VerticalList à propriedade ItemsLayout; portanto, você não precisa atribuí-lo explicitamente para obter um layout vertical. Mas, para implementar uma orientação horizontal, adicione o seguinte snippet de código ao seu XAML:

<CollectionView ItemsSource="{Binding Products}"
  It­emsLayout="{x:Static ListItemsLayout.HorizontalList}">
  ...
</CollectionView>

Na verdade, a propriedade ItemsLayout também permite definir uma exibição de grade. Neste caso, você usar a classe GridItemsLayout, em vez de ListItemsLayout, como no exemplo a seguir, que demonstra como criar uma exibição de grade horizontal:

<CollectionView x:Name="ProductList" ItemsSource="{Binding Products}" >
  <CollectionView.ItemsLayout>
    <GridItemsLayout Orientation="Horizontal" Span="3" />
  </CollectionView.ItemsLayout>
    ...
</CollectionView>

Por padrão, o GridItemsLayout mostra itens em uma única linha com o layout horizontal; portanto, você pode definir a propriedade Span para decidir quantas linhas a grade conterá. Conforme itens forem adicionados à lista de associação de dados, a exibição de grade crescerá horizontalmente. Você pode obter uma exibição de grade vertical com o seguinte código:

<CollectionView x:Name="ProductList" ItemsSource="{Binding Products}" >
  <CollectionView.ItemsLayout>
    <GridItemsLayout Orientation="Vertical" Span="2" />
  </CollectionView.ItemsLayout>
    ...
</CollectionView>

Da mesma maneira, uma grade vertical exibirá itens em uma única coluna por padrão; assim, você poderá alterar as propriedades de Span e especificar o número de colunas da grade.

Gerenciamento da seleção de itens O controle CollectionView permite selecionar um ou vários itens e desabilitar a seleção. É possível atribuir valores da enumeração Xamarin.Forms.SelectionMode à propriedade SelectionMode: None, Single e Multiple. Com None, você desabilita a seleção de itens facilmente. A propriedade SelectedItem, do objeto de tipo, representa um ou mais itens selecionados na lista. O evento SelectionChanged é gerado quando o usuário seleciona um item em CollectionView. Esse evento só funcionará se for atribuído a SelectionMode: Single (que também é o padrão caso SelectionMode não seja especificado) ou Multiple. Portanto, em seu XAML, você pode ter as atribuições a seguir:

<CollectionView x:Name="ProductList" ItemsSource="{Binding Products}"
  SelectionMode="Single" SelectionChanged="ProductList_SelectionChanged">
...
</CollectionView>

Então, o manipulador de eventos SelectionChanged permite que você gerencie a seleção de itens por meio de um parâmetro do tipo Xamarin.Forms.SelectionChangedEventArgs. Esse objeto expõe duas propriedades úteis: CurrentSelection e PreviousSelection. Como os nomes sugerem, a primeira propriedade retorna objetos selecionados no momento, enquanto a segunda retorna objetos selecionados anteriormente. Isso é muito útil, pois, em algumas situações, talvez seja útil saber quais instâncias de objeto foram realmente selecionadas antes da nova seleção. Ambas as propriedades são do tipo IReadOnlyList<object> e expõem a lista de itens selecionados. Se SelectionMode for definido como Single, você poderá recuperar a instância do item selecionado da seguinte maneira:

private void ProductList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
  var selectedProduct = this.ProductList.SelectedItem as Product;
  var singleProduct = e.CurrentSelection.FirstOrDefault() as Product;
}

Se você usar a propriedade CollectionView.SelectedItem ou o primeiro item da coleção, precisará converter o objeto resultante no tipo esperado; neste caso, Product. Se SelectionMode for definido como Multiple, primeiro você precisará converter a coleção somente leitura dos itens selecionados em uma lista de objetos do tipo esperado, da seguinte maneira:

private void ProductList_SelectionChanged(object sender,
  SelectionChangedEventArgs e)
{
  var selectedItems = e.CurrentSelection.Cast<Product>();
  foreach(var product in selectedItems)
  {
    // Handle your object properties here...
  }
}

A mesma abordagem funciona para a propriedade SelectionChangedEventArgs.PreviousSelection, na seleção de single- e multiple-item. Como uma exibição moderna, CollectionView também oferece suporte ao padrão MVVM (Model-View-ViewModel) ao processar a seleção de itens, portanto, você pode usar a propriedade SelectionChangedCommand, que pode ser associada a uma instância da classe Command no seu modelo de exibição, bem como a propriedade SelectionChangedCommandParameter, que permite transmitir um parâmetro para o comando. Por exemplo, vamos estender a classe ProductViewModel para adicionar uma propriedade SelectedProduct, que será a associação de dados da propriedade SelectedItem da CollectionView, e com um novo comando para processar a seleção. Para simplificar, a propriedade do tipo Command não usará a implementação genérica nem o parâmetro de comando. A Figura 5 mostra a aparência de modelo de exibição.

Figura 5 - Extensão do modelo de exibição com suporte para MVVM

public class ProductViewModel: INotifyPropertyChanged
{
  public ObservableCollection<Product> Products { get; set; }
  private Product _selectedProduct;
  public Product SelectedProduct
  {
    get
    {
      return _selectedProduct;
    }
    set
    {
      _selectedProduct = value;
      OnPropertyChanged();
    }
  }
  private Command _productSelectedCommand;
  public Command ProductSelectedCommand
  {
    get
    {
      return _productSelectedCommand;
    }
      set
      {
        _productSelectedCommand = value;
        OnPropertyChanged();
      }
    }
  public ProductViewModel()
  {
    // Sample products
    this.Products = new ObservableCollection<Product>();
    this.Products.Add(new Product { ProductQuantity = 50,
      ProductName = "Cheese", ProductImage = "Cheese.png" });
    this.Products.Add(new Product { ProductQuantity = 10,
      ProductName = "Water", ProductImage = "Water.png" });
    this.Products.Add(new Product { ProductQuantity = 6,
      ProductName = "Bread", ProductImage = "Bread.png" });
    this.Products.Add(new Product { ProductQuantity = 40,
      ProductName = "Tomatoes", ProductImage = "Tomato.png" });
    this.ProductSelectedCommand =
      new Command(ExecuteProductSelectedCommand,
        CanExecuteProductSelectedCommand);
  }
  private bool CanExecuteProductSelectedCommand(object arg)
  {
    return this.SelectedProduct != null;
  }
  private void ExecuteProductSelectedCommand(object obj)
  {
    // Handle your object here....
    var currentProduct = this.SelectedProduct;
  }
  public event PropertyChangedEventHandler PropertyChanged;
  private void OnPropertyChanged([CallerMemberName] string propertyName = null)
  {
    PropertyChanged?.Invoke(this,
      new PropertyChangedEventArgs(propertyName));
  }
}

Em seguida, em seu XAML, atribua as propriedades de seleção como segue:

<CollectionView x:Name="ProductList" ItemsSource="{Binding Products}"
                SelectedItem="{Binding SelectedProduct, Mode=TwoWay}"
                SelectionChangedCommand="{Binding ProductSelectionCommand}"
                SelectionMode="Single">
</CollectionView>

Com essa abordagem, você pode trabalhar em relação aos objetos selecionados no modelo de exibição, que é o lugar em que implementa a lógica de negócios, mantendo o trabalho nos dados desacoplados das exibições.

Gerenciamento de listas vazias Um dos mais importantes recursos oferecidos por CollectionView e, definitivamente, um dos meus favoritos, é a opção interna de mostrar uma exibição diferente, caso a lista de associação de dados esteja vazia, sem custo. Isso é possível por meio da propriedade EmptyView, que permite especificar a exibição que será mostrada no caso de dados vazios. Funciona assim:

<CollectionView>
...           
  <CollectionView.EmptyView>
     <Label Text="No data is available" TextColor="Red"
       FontSize="Medium"/>
  </CollectionView.EmptyView>
</CollectionView>

Esse código produz o resultado mostrado na Figura 6. Com essa abordagem, você não precisa criar um modelo de dados para os estados vazios nem implementar seletores de modelo de dados.

Fornecimento de uma exibição a estados vazios
Figura 6 - Fornecimento de uma exibição a estados vazios

Como alternativa, você pode usar a propriedade EmptyViewTemplate para implementar uma exibição personalizada. Por exemplo, o código a seguir demonstra como exibir uma imagem e uma mensagem de texto com listas vazias:

<CollectionView.EmptyViewTemplate>
  <DataTemplate>
    <StackLayout Orientation="Vertical" Spacing="20">
      <Image Source="EmptyList.png" Aspect="Fill"/>
      <Label Text="No data is available" TextColor="Red"/>
    </StackLayout>
  </DataTemplate>
</CollectionView.EmptyViewTemplate>

ScrollingCollectionView também expõe o método ScrollTo, que pode ser usado para rolar a lista programaticamente até um item especificado. O exemplo a seguir rola até o terceiro item da lista:

 

ProductList.ScrollTo(2);

Superfície de API mais simples O controle CollectionView expõe uma superfície de API mais simples do que ListView. Por exemplo, CollectionView não tem propriedades para trabalhar com separadores (como SeparatorVisibility e SeparatorColor), portanto, você pode implementar seus próprios separadores com exibições como BoxView no modelo de dados. CollectionView não implementa propriedade, como ListView.RowHeight, porque agora a altura de um item é determinada pelo primeiro item da lista. A propriedade HasUnevenRows na ListView tem um semelhante em CollectionView chamado ItemSizingStrategy. Em relação às técnicas de deslizar para atualizar, propriedades como IsPullToRefreshEnabled, IsRefreshing e RefreshCommand, expostas pela ListView, não estão disponíveis no controle CollectionView. No entanto, a Microsoft está trabalhando na implementação de propriedades compatíveis com exibições dos estados de atualização. O documento de especificação de Xamarin.Forms.CollectionView no GitHub (bit.ly/2N6iw8a) fornece uma explicação detalhada das opções de atualização e também de outras implementações de API, incluindo as decisões arquitetônicas.

Apresentação do CarouselView

O controle CarouselView não é novo no Xamarin.Forms 4.0. No entanto, ele foi completamente recriado com base na estrutura e no desempenho do CollectionView.

Com o CarouselView, você pode mostrar um objeto da lista por vez, em um formato de cartão. A Figura 7, extraída do blog oficial do Xamarin (bit.ly/2BwWMNV), mostra como o CarouselView oferece uma maneira de passar o dedo entre itens.

O CarouselView mostra itens na forma de cartões, habilitando o gesto de passar o dedo
Figura 7 - O CarouselView mostra itens na forma de cartões, habilitando o gesto de passar o dedo

Com relação ao código de exemplo descrito anteriormente, você pode usar o CarouselView para exibir a lista de produtos como cartões, conforme mostrado na Figura 8.

Figura 8 - Exibição de itens como cartões com o CarouselView

<CarouselView x:Name="ProductList" ItemsSource="{Binding Products}">
  <CarouselView.ItemsLayout>
    <GridItemsLayout Orientation="Horizontal"
                     SnapPointsAlignment="Center"
                     SnapPointsType="Mandatory"/>
  </CarouselView.ItemsLayout>
  <CarouselView.ItemTemplate>
    <DataTemplate>
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="24"/>
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Image Source="{Binding ProductImage}" HeightRequest="22" />
        <StackLayout Grid.Column="1" Orientation="Vertical"
                     Spacing="5">
          <Label Text="{Binding ProductName}" FontSize="Medium"
                 TextColor="Blue"/>
          <Label Text="{Binding ProductQuantity}" FontSize="Small"
                 TextColor="Black"/>
        </StackLayout>
      </Grid>
    </DataTemplate>
  </CarouselView.ItemTemplate>
  <CarouselView.EmptyView>
    <Label Text="No data is available" TextColor="Red"
           FontSize="Medium"/>
  </CarouselView.EmptyView>
</CarouselView>

Vamos nos concentrar nos pontos principais do código.

Declaração do CarouselView A declaração do CarouselView no XAML é bem semelhante à declaração do CollectionView. Ainda é necessário associar a propriedade ItemsSource à coleção de dados que você deseja exibir. Você também pode fornecer exibições de estados vazios, exatamente como fez com o CollectionView.

Orientação O CarouselView oferece suporte às orientações horizontal e vertical. Você atribui uma instância GridItemsLayout à propriedade ItemsLayout, passando Horizontal ou Vertical para a propriedade Orientation.

Adição de pontos de ajuste Com as propriedades SnapPointsAlignment e SnapPointsType no ItemsLayout, você pode configurar o comportamento do cartão. Por exemplo, na Figura 8 as propriedades SnapPointsType e SnapPointsAlignment garantem que o cartão apareça centralizado. Sem essas atribuições, parte do cartão pararia entre os outros cartões. Os valores permitidos para SnapPointsAlignment são Center, End e Start. Os valores permitidos para SnapPointsType são Mandatory, MandatorySingle e None.

Assim como acontece com CollectionView, lembre-se de que os bits finais podem fornecer uma implementação de API diferente. Com a versão prévia atual, você também pode experimentar uma InvalidCastException quando o aplicativo estiver renderizando a exibição. É uma compilação instável e problemas desse tipo são esperados.

Criação de interfaces do usuário consistentes com a propriedade Visual

O Xamarin. Forms 4.0 introduz uma nova maneira de os desenvolvedores criarem interfaces do usuário praticamente idênticas no Android e no iOS, com quase nenhum esforço. A chave é uma nova propriedade chamada Visual, exposta pela classe VisualElement. A propriedade Visual garante que renderizadores novos e adicionais sejam usados para desenhar elementos visuais, em vez do renderizador padrão. No estado atual da versão prévia, o Xamarin.Forms 4.0 inclui um mecanismo de renderização experimental baseado em design de material, atualmente disponível para as seguintes exibições: Button, Entry, Frame e ProgressBar. Você pode habilitar a nova renderização de visual desta maneira:

 

<Entry Visual="Material" />

A Figura 9, extraída das notas sobre a versão da Microsoft para o Xamarin.Forms 4.0 (bit.ly/2BB4MxA), mostra um exemplo de uma interface do usuário consistente entre Android e iOS, criado usando o Visual.

Interfaces do usuário consistentes com a propriedade do Visual
Figura 9 - Interfaces do usuário consistentes com a propriedade do Visual

Você também pode atribuir a propriedade do Visual no nível de ContentPage para garantir que qualquer uma das exibições compatíveis em seu código usará o design especificado. Para usar o Visual, seu projeto deve atender a alguns requisitos:

  • No projeto do iOS, o pacote Xamarin.iOS.MaterialComponents do NuGet deve estar instalado. Porém, ele é instalado automaticamente quando você atualiza o pacote Xamarin.Forms para 4.0.
  • Para o Android, seu projeto deve ser baseado na API 29 e as bibliotecas de suporte devem usar a versão 28. Além disso, o tema do aplicativo deve herdar de um dos temas dos Componentes Materiais.

É importante observar que o desenvolvimento do Visual está só no começo. Portanto, os desenvolvedores podem esperar muitas atualizações. De maneia geral, é uma adição extremamente útil que poupará muito tempo ao criar interfaces do usuário idênticas entre plataformas diferentes.

Outros aperfeiçoamentos

No Xamarin.Forms 4.0, agora você pode especificar uma cor para o controle giratório quando a função deslizar para atualizar está habilitada. Isso é feito atribuindo a propriedade RefreshControlColor da seguinte maneira:

<ListView RefreshControlColor="Green"/>

Além disso, no ListView é possível ocultar as barras de rolagem sem escrever renderizadores personalizados, basta atribuir as propriedades HorizontalScrollBarVisibility e VerticalScrollBarVisibility:

<ListView HorizontalScrollBarVisibility="Always"
  VerticalScrollBarVisibility="Never"/>

Os valores possíveis são Always (sempre visível), Never (nunca visível) e Default (com base no padrão da plataforma de destino).  Além disso, o controle Editor agora inclui suporte para previsão de texto, como no controle Entry. Você pode simplesmente atribuir True ou False à propriedade IsTextPredictionEnabled, da seguinte maneira:

<Editor IsTextPredictionEnabled="True" />

Com o Xamarin.Forms 4.0, a exibição SwitchCell recebe a propriedade OnColor, assim como a exibição Switch recebia nas versões principais anteriores. Assim, agora você pode definir uma cor diferente para o estado ativo ao usar SwitchCell em seus modelos de dados:

<SwitchCell OnColor="Red"/>

Essas são as melhorias mais interessantes do ponto de vista prático, mas a lista completa de atualizações e problemas corrigidos está disponível na página de notas sobre a versão e será atualizada eventualmente, assim que o Xamarin.Forms 4.0 finalmente for liberado para produção.

Uma olhada rápida no Xamarin.Forms no Visual Studio 2019

Recentemente, a Microsoft lançou o Visual Studio 2019 Preview 3 (bit.ly/2QcOK6z), que fornece uma visão antecipada das novidades que estarão na próxima versão principal do Visual Studio, incluindo suporte para Xamarin.Forms 4.0. Por exemplo, um novo modelo de projeto chamado Shell agora está disponível na caixa de diálogo de novo aplicativo multiplataforma (consulte a Figura 10). Esse modelo gera um novo projeto com base no recurso Shell, com várias exibições especificadas no objeto Shell, no código XAML da página principal.

O novo modelo de projeto baseado no Shell
Figura 10 - O novo modelo de projeto baseado no Shell

O Visual Studio 2019 também traz para o Xamarin.Forms um novo painel Propriedades, mostrado na Figura 11, que já estava disponível para outras plataformas de desenvolvimento. Ele exibe valores de propriedade quando você clica em uma exibição no código XAML ou no Pré-visualizador do Xamarin.Forms.

O novo painel Propriedades
Figura 11 - O novo painel Propriedades

Se você alterar os valores da propriedade utilizando o painel Propriedades, o código XAML será atualizado automaticamente para refletir as alterações. Note como editores específicos estão disponíveis para alguns tipos, como o editor de cor para propriedades do tipo Xamarin.Forms.Color.

Conclusão

Como nas versões principais anteriores, o Xamarin.Forms 4.0 demonstra o enorme investimento que a Microsoft está fazendo para melhorar a experiência de desenvolvimento, não somente com novos recursos, mas também tornando as ferramentas e a base de código existentes cada vez mais confiáveis, que é o que os desenvolvedores precisam em seus projetos reais. Será interessante ver quais outras novidades serão apresentadas na próxima conferência Microsoft Build, que acontecerá em Seattle, de 6 a 8 de maio.


Alessandro Del Soleé MVP da Microsoft desde 2008 e um Desenvolvedor Certificado do Xamarin. Ele é autor de muitos livros, eBooks, vídeos instrutivos e artigos sobre o desenvolvimento em .NET com o Visual Studio. Del Sole trabalha na Fresenius Medical Care como engenheiro sênior de software, concentrando-se na criação de aplicativos móveis e em .Net com o Xamarin, no mercado de serviços de saúde. Você pode segui-lo no Twitter: @progalex.

Agradecemos aos seguintes especialistas técnicos da Microsoft pela revisão deste artigo: Paul DiPietro