imagem ptototipo

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.

plugin

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>
gif abas

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

Modificado pela ultima vez: 15 de maio de 2020

Comentários

Escreva uma resposta ou comentário

Seu endereço de e-mail não será publicado.

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.