Recentemente tive a necessiade de “adicionar uma tabbedpage dentro de Content Page”. Basicamente a necessidade era ter dentro da minha página duas abas, mais ou menos como o protótipo abaixo:Para atender este cenário, utilizei o plugin Xam.Plugins.TabView que emula o comportamento de abas utilizando um outro plugin de CarouselView.
Neste post vamos ver um pouco mais sobre o funcionamento deste plugin.
O plugin TabView
O plugin é open source e o código fonte dele está disponível no GitHub, clique aqui para acessar o repositório.
Este plugin utiliza um outro plugin para emular o efeito de abas, o CarouselView
Vamos instalar o plugin no projeto .Net Standart e em todas as plataformas. Procure o plugin pelo nome Xam.Plugins.TabView e instale a ultima versão estável.
Você verá que além do TabView também foi instalado o CarouselView.
Vamos iniciar o CarouselView nos projetos das plataformas específicas. Para isto, acesse a classe MainActivity.cs do projeto Android e adicione a linha abaixo após a inicialização do Xamarin Forms:
CarouselViewRenderer.Init();
No projeto iOS vamos acessar a classe AppDelegate.cs e adicionar a linha abaixo:
CarouselViewRenderer.Init();
Até o momento deste post a versão disponível do plugin não está compatível com instanciação no XAML, pois não possui um construtor sem parametros. Já existe uma issue no repositório para a disponibilização da versão.
Para usar o plugin na página XAML, vamos criar uma nova classe que irá herdar do plugin e adicionar um construtor sem parametros para que seja possível utiliza-lo no XAML, veja abaixo:
namespace App.Controls
{
[ContentProperty(nameof(ItemSource))]
public class TabView : Xam.Plugin.TabView.TabViewControl
{
public TabView() : base(new List<Xam.Plugin.TabView.TabItem>(), -1)
{
}
}
[ContentProperty(nameof(Content))]
public class TabItem : Xam.Plugin.TabView.TabItem
{
public TabItem() : base("", new ContentView())
{
}
}
}
Vamos referenciar esta classe na nossa MainPage.xaml, como um control, veja abaixo:
xmlns:controls="clr-namespace:App.Controls;assembly=App"
Agora que o nosso control já está referenciado na página, podemos utiliza-lo para criar nossa “tabbed page” dentro da nossa ContentPage
<ContentPage x:Class="App.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:App.Controls;assembly=App"
xmlns:local="clr-namespace:App">
<StackLayout Margin="30">
<controls:TabView x:Name="TabView"
HeaderBackgroundColor="Transparent"
HeaderSelectionUnderlineColor="#84888b"
HeaderSelectionUnderlineThickness="3"
HeaderSelectionUnderlineWidth="164"
HeaderTabTextColor="#84888b">
<controls:TabItem HeaderTabTextFontSize="14"
HeaderText="Aba 1"
HeaderTextColor="#84888b">
<StackLayout>
<Label Text="Conteudo Aba 1" />
</StackLayout>
</controls:TabItem>
<controls:TabItem HeaderTabTextFontSize="14"
HeaderText="Aba 2"
HeaderTextColor="#84888b">
<StackLayout>
<Label Text="Conteudo Aba 2" />
</StackLayout>
</controls:TabItem>
</controls:TabView>
</StackLayout>
</ContentPage>
Veja que tudo começa com uma nova TabView, que por sua vez contém TabItem, cada TabItem será uma nova aba e o TabView o container de todas as abas.
Importante ressaltar que dentro da sua TabView e TabItems você estará dentro de um contexto de binding diferente do contexto de binding da página. Se você estiver trabalhando com MVVM e quiser buscar valores da sua View Model, você precisará dar um nome a página com o atributo x:Name e realizar a troca do contexto de binding, veja um exemplo abaixo:
<ContentPage x:Class="App.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:App.Controls;assembly=App"
xmlns:local="clr-namespace:App"
x:Name="Pagina">
<StackLayout Margin="30">
<controls:TabView x:Name="TabView"
HeaderBackgroundColor="Transparent"
HeaderSelectionUnderlineColor="#84888b"
HeaderSelectionUnderlineThickness="3"
HeaderSelectionUnderlineWidth="164"
HeaderTabTextColor="#84888b">
<controls:TabItem HeaderTabTextFontSize="14"
HeaderText="Aba 1"
HeaderTextColor="#84888b">
<StackLayout>
<Label Text="{Binding Source={x:Reference Pagina}, Path=BindingContext.Texto}" />
</StackLayout>
</controls:TabItem>
<controls:TabItem HeaderTabTextFontSize="14"
HeaderText="Aba 2"
HeaderTextColor="#84888b">
<StackLayout>
<Label Text="Conteudo Aba 2" />
</StackLayout>
</controls:TabItem>
</controls:TabView>
</StackLayout>
</ContentPage>
OBS: Se na sua página você estiver trabalhando com itens na tela que a largura total seja maior que largura da tela, como um ScrollView horizontal por exemplo, utilize apenas o plugin CarosselView. Este plugin encontra algumas dificuldades na montagem da tela na plataforma iOS.
Conclusão
O plugin ajuda a emular o efeito de ter uma TabbedPage dentro de ContentPage. Basicamente o plugin utiliza um outro plugin CarouselView e nada nos impediria de a partir do plugin CarouselView criarmos nossa própria implementação. O pluguin abstraiu algumas implementações e nos economiza um pouco de tempo. Fica a critério da pessoa desenvolvedora.
Você pode baixar o código fonte deste post no meu GitHub
—
#Ubuntu
Imagem utilizada no post PixaBay
Comentários