Saltar al contenido
CrossFly es 100% open sourceSíguenos en GitHub
CrossFlyCrossFly
Empezar

Esta página fue traducida automáticamente del portugués y puede contener errores. La versión en portugués es la canónica.

TabBar

TabBar es una barra de pestañas: una tira de botones (tab strip) + un panel de contenido desplazable horizontalmente con snap por página (vía PageScrollEngine). Tocar una pestaña desplaza el contenido hasta la página correspondiente; arrastrar el contenido cambia la pestaña activa. Un indicador animado acompaña a la pestaña activa.

La estética (indicador, pestañas arriba o abajo, colores) viene del Skin activo (TabBarStyle). Cada pestaña se describe con un TabBar.Tab (texto, ícono o ambos).

🟡 · Paquete: dev.crossfly.ui · Extiende: Component · Estilo: TabBarStyle (vía getSkin().tabBar())

Cuándo usar

  • Navegación entre 2–5 secciones de una pantalla (Inicio / Buscar / Perfil).
  • Contenido paginado con gesto de swipe entre páginas + pestañas sincronizadas.

Cuándo NO usar

  • Muchas secciones que no caben (la tira se desplaza, pero queda menos legible) → considera otra navegación.

Apariencia

Tira de pestañas de igual ancho (1/n); si no caben, la tira pasa a ser desplazable horizontalmente y las pestañas pasan a ancho automático. El indicador se desliza bajo (o sobre, si tabsAtBottom) la pestaña activa. El panel de contenido muestra una página a la vez con snap.

Ejemplo completo (copiar, pegar y ejecutar)

package com.exemplo;

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

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // Una view de contenido por pestaña (el conteo TIENE que coincidir con el número de pestañas).
      Label resumo    = new Label("Conteúdo do Resumo");
      Label detalhes  = new Label("Conteúdo dos Detalhes");
      Label historico = new Label("Conteúdo do Histórico");

      TabBar tabs = new TabBar(
         new TabBar.Tab("Resumo"),
         new TabBar.Tab("Detalhes"),
         new TabBar.Tab("Histórico"));
      tabs.setContent(resumo, detalhes, historico);
      tabs.onTabChanged(i -> System.out.println("aba " + i));

      add(LAY_FILL, tabs);   // la TabBar absorbe la altura restante
   }
}

Los fragmentos de abajo muestran solo el núcleo (lo que va dentro de onShow()). Para ejecutarlos, colócalos en el esqueleto MainWindow de arriba.

Uso básico

TabBar tabs = new TabBar(
   new TabBar.Tab("Home",   new MaterialIcon("")),
   new TabBar.Tab("Buscar", new MaterialIcon("")),
   new TabBar.Tab("Perfil", new MaterialIcon("")));
tabs.setContent(homeView, searchView, profileView);
tabs.onTabChanged(i -> System.out.println("aba " + i));
add(LAY_FILL, tabs);

Constructores

Constructor Descripción
TabBar(Tab... tabs) Crea la barra con las pestañas (activeIndex = 0)

TabBar.Tab (descriptor de pestaña)

Constructor Resultado
Tab(String text) Solo texto (TextPos.NONE)
Tab(Icon icon) Solo ícono (TextPos.NONE)
Tab(String text, Icon icon) Texto + ícono (TextPos.TEXT_AT_BOTTOM)
Tab(String text, Icon icon, TextPos textPos) Texto + ícono con posición personalizada

Propiedades y personalización

Propiedad / método Tipo Qué hace
setContent(Component...) TabBar Contenido por pestaña (la cantidad debe coincidir con las pestañas, si no IllegalArgumentException)
setActiveTab(int) TabBar Activa una pestaña programáticamente (con animación/scroll); no-op si es inválido o ya está activo
getActiveIndex() int Índice de la pestaña activa
getTabs() Tab[] Descriptores de las pestañas
getStrip() / getTabButtons() / getContentPanel() — Acceso a los internos
getIndicatorX() / getIndicatorW() float Posición/ancho actuales del indicador (para pintura en el Design)

Callbacks y eventos

Callback Cuándo se dispara
onTabChanged(TabChangedListener) Al cambiar de pestaña, por toque, swipe o setActiveTab(...)

TabChangedListener es funcional: void onTabChanged(int index).

Estados

  • Activa — solo una pestaña a la vez; el indicador anima hasta ella (duración TabBarStyle.switchDuration).
  • Swipe del usuario — el indicador interpola continuamente entre pestañas vecinas; al cruzar hacia otra página, activeIndex cambia y onTabChanged se dispara.
  • Programático — setActiveTab/toque bloquean la sincronización hasta que la animación de scroll llega al objetivo.

Pestañas solo de texto

TabBar tabs = new TabBar(
   new TabBar.Tab("Resumo"),
   new TabBar.Tab("Detalhes"),
   new TabBar.Tab("Histórico"));
tabs.setContent(resumoView, detalhesView, historicoView);
add(LAY_FILL, tabs);

Cambio programático de pestaña

TabBar tabs = new TabBar(new TabBar.Tab("A"), new TabBar.Tab("B"), new TabBar.Tab("C"));
tabs.setContent(viewA, viewB, viewC);
add(LAY_FILL, tabs);
// ... más tarde:
tabs.setActiveTab(2);  // anima hasta la pestaña C

Buenas prácticas

  • La cantidad de setContent(...) tiene que coincidir con el número de pestañas.
  • Para pestañas abajo (estilo iOS), usa un Skin cuyo TabBarStyle.tabsAtBottom = true — el layout y el indicador se ajustan solos.
  • No fuerces ancho fijo en las pestañas: si no caben, la tira se desplaza por su cuenta.

Errores comunes

  • setContent con cantidad incorrecta → IllegalArgumentException. Pasa exactamente una view por pestaña.
  • Esperar que setActiveTab dispare onTabChanged para el índice ya activo — es no-op cuando index == activeIndex.

Véase también

¿Te resultó útil esta página?