Pular para o conteúdo
CrossFly é 100% open sourceSiga no GitHub
CrossFlyCrossFly
Começar

Como criar abas (TabBar)

Propósito. Organizar conteúdo em páginas comutáveis por uma barra de abas, com indicador animado e deslize horizontal entre páginas. Use para seções de nível superior (Home / Buscar / Perfil) ou para agrupar conteúdo relacionado sem navegação de tela.

APIs usadas

  • new TabBar(TabBar.Tab... tabs) — cria a barra a partir de descritores de aba.
  • new TabBar.Tab(String text) — aba só texto.
  • new TabBar.Tab(Icon icon) — aba só ícone.
  • new TabBar.Tab(String text, Icon icon) — aba com texto e ícone (texto abaixo do ícone por default).
  • tabBar.setContent(Component... contents) — define o conteúdo de cada aba; a quantidade deve bater com o número de abas (senão lança IllegalArgumentException).
  • tabBar.onTabChanged(TabBar.TabChangedListener listener) — callback onTabChanged(int index) chamado quando a aba ativa muda (por toque ou por deslize).
  • tabBar.setActiveTab(int index) — troca a aba programaticamente (anima indicador e rola o conteúdo).
  • tabBar.getActiveIndex() — índice da aba ativa.

Exemplo completo (copiar, colar e rodar)

package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;

/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // Abas só-texto (autônomas, sem depender de glyphs de MaterialIcon)
      TabBar tabBar = new TabBar(
         new TabBar.Tab("Início"),
         new TabBar.Tab("Buscar"),
         new TabBar.Tab("Perfil"));

      // Um Component de conteúdo por aba, na MESMA ordem das abas
      Component telaInicio = new Label("Conteúdo: Início");
      Component telaBusca  = new Label("Conteúdo: Buscar");
      Component telaPerfil = new Label("Conteúdo: Perfil");

      tabBar.setContent(
         telaInicio,
         telaBusca,
         telaPerfil);

      tabBar.onTabChanged(index ->
      {
         // ex.: carregar dados sob demanda quando a aba muda
         if (index == 1) carregarBusca();
      });

      add(LAY_FILL, tabBar);
   }

   private void carregarBusca()
   {
      // ... carregar dados da aba Buscar sob demanda ...
   }
}

O trecho abaixo mostra só o miolo. Para rodar, coloque-o no esqueleto MainWindow acima.

Trecho mínimo

TabBar tabBar = new TabBar(
   new TabBar.Tab("Início",  new MaterialIcon("")),
   new TabBar.Tab("Buscar",  new MaterialIcon("")),
   new TabBar.Tab("Perfil",  new MaterialIcon("")));

// Um Component de conteúdo por aba, na MESMA ordem das abas
tabBar.setContent(
   telaInicio,
   telaBusca,
   telaPerfil);

tabBar.onTabChanged(index ->
{
   // ex.: carregar dados sob demanda quando a aba muda
   if (index == 1) carregarBusca();
});

add(tabBar);

// Trocar de aba por código, se precisar:
tabBar.setActiveTab(2);   // vai para "Perfil"

Nota de verificação (código 2026). Confirmado na fonte: TabBar(Tab...), setContent(Component...), onTabChanged(TabChangedListener), setActiveTab(int). Detalhes de comportamento: a barra de abas escorrega horizontalmente quando as abas não cabem; deslizar o painel de conteúdo troca a aba ativa e move o indicador; o posicionamento das abas (topo vs. base) e o estilo do indicador vêm da TabBarStyle do Skin ativo (ex.: IOSSkin coloca as abas na base). Se setContent não for chamado, a barra mostra só as abas sem painel de conteúdo.

Aprofunde-se

  • Página do widget: TabBar · Fonte canônica: Capítulo 14
  • Navegação entre telas (alternativa a abas): Navegação
Esta página foi útil?