diegoRodicio

Está documentación está a túa disposición sin ningún custo económico. Sen embargo, para a súa elaboración dedico moito tempo e recursos, polo que agradecería unha colaboración co que consideres oportuno. Gracias.

View Categories

🏗️ Scaffold

Contido:

Xa introducimos Scaffold como o esqueleto básico dunha pantalla de Material Design. Agora, imos explorar algúns dos seus outros compoñentes e propiedades útiles.

Scaffold proporciona a maioría dos patróns visuais de Material Design, incluíndo:

  • appBar: A barra superior da aplicación.
  • body: Contido principal da pantalla.
  • floatingActionButton: Un botón de acción flotante.
  • floatingActionButtonLocation: Controla a posición do floatingActionButton.
  • drawer: Menú lateral. É un panel que se desliza dende o bordo da pantalla (normalmente á esquerda), común para menús de navegación.
  • bottomNavigationBar: Unha barra inferior de navegación.
  • bottomSheet: Un panel que se desliza dende a parte inferior da pantalla, útil para contido temporal.
  • snackBar: Mensaxes temporais que aparecen na parte inferior da pantalla.

🏗️ Exemplo de Scaffold básico #

Scaffold(
  appBar: AppBar(
    title: const Text('Exemplo con Scaffold'),
  ),
  body: const Center(
    child: Text('Contido principal'),
  ),
  floatingActionButton: FloatingActionButton(
    onPressed: () {
      print('Botón premido');
    },
    child: const Icon(Icons.add),
  ),
)

🧭 A AppBar: a barra superior da túa aplicación #

A AppBar é a barra que aparece na parte superior da pantalla nunha app de Material Design. Normalmente contén:

  • Un título (nome da pantalla ou da app).
  • Un botón de navegación (frecha de “atrás” ou menú tipo “hamburguesa”).
  • Un conxunto de accións (icona de buscar, configurar, gardar, etc.).

Nun Scaffold, defínese coa propiedade appBar:

Scaffold(
  appBar: AppBar(
    title: const Text('Pantalla principal'),
  ),
  body: const Center(
    child: Text('Contido principal'),
  ),
);

🔍 Estrutura visual dunha AppBar #

De maneira esquemática, unha AppBar típica podería verse así:

  • leading: widget da esquerda (icona de menú, frecha de volver, avatar…).
  • title: título principal da pantalla.
  • actions: lista de widgets (normalmente IconButton) á dereita.

⚙️ Propiedades máis frecuentes de AppBar #

PropiedadeDescriciónExemplo
titleDefine o título da barra. Adoita ser un Text.title: const Text('Inicio')
centerTitleIndica se o título vai centrado (true) ou aliñado á esquerda (false, por defecto en Android).centerTitle: true
leadingWidget que aparece á esquerda: icona de menú, frecha de voltar, avatar… Se non se indica, Flutter adoita poñer a frecha.leading: IconButton(icon: Icon(Icons.menu), onPressed: ... )
actionsLista de widgets á dereita (normalmente iconas de acción).actions: [ IconButton(icon: Icon(Icons.search), onPressed: ... ) ]
backgroundColorCor de fondo da AppBar.backgroundColor: Colors.blue
foregroundColorCor por defecto para texto e iconas da AppBar.foregroundColor: Colors.white
elevationSombra baixo a barra (máis ou menos “altura”).elevation: 4
automaticallyImplyLeadingSe false, evita que Flutter engada automaticamente a frecha de voltar ou icona de menú.automaticallyImplyLeading: false
flexibleSpaceZona flexible detrás do contido, útil para degradados, imaxes ou efectos de colapso.flexibleSpace: Container(decoration: BoxDecoration(gradient: ...))
bottomWidget que se coloca na parte inferior da AppBar, moi usado con TabBar.bottom: TabBar(tabs: [...])

🧪 Exemplo: AppBar #

💡 Nota: neste exemplo aínda non creamos un menú de navegación real que se amosa no leading; iso farémolo na seguinte sección empregando a propiedade drawer do Scaffold.

🔗 Ver o código en DartPad

🎨 Personalizar a AppBar co tema da app #

Aínda que podes configurar cada AppBar de forma individual, é habitual definir un estilo xeral no ThemeData da túa MaterialApp, usando appBarTheme. Por exemplo:

MaterialApp(
  title: 'App co seu tema',
  theme: ThemeData(
    useMaterial3: true,
    appBarTheme: const AppBarTheme(
      backgroundColor: Colors.deepPurple,
      foregroundColor: Colors.white,
      centerTitle: true,
      elevation: 2,
    ),
  ),
  home: const MiPantallaPrincipal(),
);

Desta maneira, todas as AppBar da app herdan este estilo por defecto, e só tes que modificar propiedades concretas cando necesites algo especial.

🟢 FloatingActionButton e FloatingActionButtonLocation #

O floatingActionButton (FAB) é un dos elementos máis recoñecibles do deseño Material Design. É un botón circular que flota sobre o contido e que se usa para realizar a acción principal dunha pantalla (engadir, crear, escribir, etc.).

🚀 Que é o ‌FloatingActionButton? #

É un botón flotante que aparece normalmente na esquina inferior dereita.
Adoita representar a acción máis importante dunha pantalla:

  • Engadir un elemento novo
  • Crear unha tarefa
  • Escribir unha mensaxe
  • Abrir un menú de accións

Exemplo básico:

floatingActionButton: FloatingActionButton(
  onPressed: () {
    print("FAB premido!");
  },
  child: const Icon(Icons.add),
)

⚙️ Propiedades importantes do FloatingActionButton‌ #

PropiedadePara que serve
onPressedAcción ao premer o FAB (obrigatoria).
childNormalmente unha icona.
tooltipTexto que aparece ao manter o dedo enriba (accesibilidade).
backgroundColorCor do botón.
foregroundColorCor da icona.
elevationSombra.
shapeForma do botón (circular, rectangular, pill…).

Exemplo básico de FloatingActionButton #

floatingActionButton: FloatingActionButton(
  onPressed: () {},
  tooltip: 'Engadir tarefa',
  backgroundColor: Colors.deepPurple,
  foregroundColor: Colors.white,
  elevation: 4,
  child: const Icon(Icons.add),
),

📍 FloatingActionButtonLocation #

O FAB pode colocarse en diferentes puntos da pantalla. Flutter permite controlalo coa propiedade:

floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,

As diferentes posicións posibles do FAB foron detalladas na sección previa dos apuntes.

🧪 Exemplo completo #

🔗 Ver o código en DartPad

🎨 Consellos prácticos #

  • Usa o FAB só para a acción principal da pantalla.
  • Non abuses del: unha pantalla = un FAB.
  • Se hai varias accións, considera usar un SpeedDial (expandir botón con máis opcións).
  • Evita poñelo enriba de elementos interactivos importantes.

🧭 A Drawer: o menú lateral en Flutter #

O Drawer é un panel lateral que se desliza desde o bordo esquerdo da pantalla. É un patrón de navegación moi común en apps con moitas seccións ou categorías. Forma parte dos compoñentes estándar de Material Design e intégrase directamente no Scaffold.

🔹 Que é un Drawer? #

É un menú lateral oculto que aparece ao deslizar o dedo dende a esquerda ou ao premer o botón de menú (leading) na AppBar. Permite navegar entre pantallas da aplicación ou executar accións rápidas.

📌 Como se engade un Drawer? #

Dentro dun Scaffold basta con definir a propiedade:

drawer: Drawer(
  child: ListView(
    padding: EdgeInsets.zero,
    children: [
      DrawerHeader(
        decoration: BoxDecoration(color: Colors.blue),
        child: Text('Menú'),
      ),
      ListTile(
        leading: Icon(Icons.home),
        title: Text('Inicio'),
        onTap: () {
          Navigator.pop(context); // Pecha o Drawer
        },
      ),
    ],
  ),
),

🧱 Estrutura habitual dun Drawer #

ElementoPara que serve
DrawerHeaderZona superior do menú. Úsase para mostrar o nome da app, avatar, imaxe ou información do usuario.
ListTileCada opción do menú. Pode incluír icono, título e acción ao premer.
DividerLiña separadora entre grupos de opcións.
Navigator.popPecha o Drawer despois de premer unha opción.

🧪 Exemplo completo dun Drawer simple #

🔗 Ver o código en DartPad

🔁 Drawer vs endDrawer #

Flutter tamén permite un menú lateral na dereita mediante:

endDrawer: Drawer(...)

Isto é útil cando:

  • a app ten dous paneis de navegación,
  • se quere separar “menú principal” e “opcións secundarias”,
  • ou cando o deseño segue patróns RTL (right‑to‑left).

📝 Consellos prácticos #

  • O leading da AppBar mostra automaticamente o icono ☰ se hai un drawer definido.
  • Sempre que remates unha acción dentro do menú, chama a Navigator.pop(context) para pechalo.
  • Para navegación avanzada, combina Drawer con Navigator.push() ou GoRouter.

🧭 A BottomNavigationBar: a barra de navegación inferior #

A BottomNavigationBar é un dos patróns de navegación máis utilizados en Flutter. Permite que o usuario cambie entre diferentes seccións principais da app mediante iconas e textos situados na parte inferior da pantalla.

É especialmente útil cando:

  • Tes entre 2 e 5 seccións principais.
  • Queres que o usuario poida cambiar rapidamente entre pantallas.
  • Precisas navegación persistente entre vistas.

🔹 Como funciona a BottomNavigationBar #

Forma parte do Scaffold e defínese coa propiedade:

bottomNavigationBar: BottomNavigationBar(...)

⚠️ Nunha app con estado, adoita ir acompañada dun índice que identifica que pestana está activa:

int _indiceActual = 0;

⚙️ Propiedades máis importantes #

PropiedadePara que serve
itemsLista de BottomNavigationBarItem que forman o menú.
currentIndexIndica cal é a pestana seleccionada.
onTapCallback que se executa ao premer unha pestana.
typePode ser fixed ou shifting. shifting anímase ao cambiar, útil con 3+ opcións con cores diferentes.
selectedItemColorCor dos elementos seleccionados.
unselectedItemColorCor dos elementos non seleccionados.
backgroundColorCor de fondo da barra.
elevationSombra baixo a barra.

📌 Exemplo básico dunha BottomNavigationBar #

Scaffold(
  bottomNavigationBar: BottomNavigationBar(
    currentIndex: _indiceActual,
    onTap: (index) {
      setState(() {
        _indiceActual = index;
      });
    },
    items: const [
      BottomNavigationBarItem(
        icon: Icon(Icons.home),
        label: 'Inicio',
      ),
      BottomNavigationBarItem(
        icon: Icon(Icons.person),
        label: 'Perfil',
      ),
    ],
  ),
);

🔁 Navegación condicionada polo índice #

Un patrón moi común:

Widget _construirPantalla() {
  switch (_indiceActual) {
    case 0:
      return const PantallaInicio();
    case 1:
      return const PantallaMensaxes();
    case 2:
      return const PantallaAxustes();
    default:
      return const PantallaInicio();
  }
}

E no Scaffold:

body: _construirPantalla(),

🎨 Consellos prácticos #

  • Non uses máis de 5 elementos, xa que rompe as guías de Material Design.
  • Se precisas navegación máis complexa, considera NavigationBar (Material 3), NavigationRail ou GoRouter.
  • Para apps grandes, combínase con IndexedStack para manter o estado das pantallas.

🧪 Exemplo completo #

🔗 Ver o código en DartPad

🧭 bottomSheet: paneis que se deslizan dende abaixo #

O bottomSheet é un compoñente de Material Design que aparece dende a parte inferior da pantalla. Úsase para mostrar contido adicional sen navegar a unha nova pantalla: opcións rápidas, formularios curtos, listas, información temporal, etc.

Flutter ofrece dúas variantes:

  • Bottom Sheet fixo → permanece visible na parte inferior.
  • Bottom Sheet modal → aparece sobre a interface e pode pecharse deslizando ou tocando fóra.

Aquí verás ambas opcións.

🔹 1. Bottom Sheet fixo (definido no Scaffold) #

É un panel que permanece ancorado na parte inferior da pantalla. Defínese coa propiedade bottomSheet do Scaffold.

Scaffold(
  bottomSheet: Container(
    color: Colors.blueGrey[50],
    height: 80,
    padding: const EdgeInsets.all(16),
    child: const Center(
      child: Text(
        'Isto é un bottomSheet fixo',
        style: TextStyle(fontSize: 16),
      ),
    ),
  ),
  body: const Center(child: Text('Contido principal')),
);

📌 Características:

  • Sempre visible.
  • Non se pecha automaticamente.
  • Non bloquea o contido principal.

🔹 2. Bottom Sheet modal (o máis usado) #

O modal bottom sheet é o tipo máis común. Aparece sobre todos os elementos e pode incluír listas, formularios, botóns, etc.

📝 Chámase mediante showModalBottomSheet, normalmente desde un botón:

FloatingActionButton(
  child: const Icon(Icons.more_vert),
  onPressed: () {
    showModalBottomSheet(
      context: context,
      builder: (context) => Text("Texto do modal"),
    );
  },
)

🔎 Nota: O exemplo anterior é o máis simple posible e funciona correctamente, pero o modal aparecerá moi pequeno porque só contén un Text. En aplicacións reais adoita usarse un Container ou unha Column para ofrecer unha presentación máis clara e cómoda:

FloatingActionButton(
  child: const Icon(Icons.more_vert),
  onPressed: () {
    showModalBottomSheet(
      context: context,
      builder: (context) {
        return Container(
          padding: const EdgeInsets.all(20),
          child: Column(
            mainAxisSize: MainAxisSize.min,   // O modal adapta a altura ao contido
            children: const [
              Text(
                'Opcións rápidas',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),
              SizedBox(height: 10),
              ListTile(
                leading: Icon(Icons.share),
                title: Text('Compartir'),
              ),
              ListTile(
                leading: Icon(Icons.delete),
                title: Text('Eliminar'),
              ),
            ],
          ),
        );
      },
    );
  },
)

🔧 Propiedades útiles en showModalBottomSheet #

PropiedadePara que serve
isScrollControlledPermite que o panel ocupe máis altura (ata pantalla completa).
shapePara bordes redondeados.
backgroundColorDefine a cor do panel.
enableDragPermite pechar arrastrando.

🧪 Exemplo completo #

🔗 Ver o código en DartPad

Este patrón é perfecto para listas longas, menús complexos ou filtros.

🎨 Consellos de uso #

  • Usa bottom sheets para accións rápidas ou contidos complementarios.
  • Se o contido é grande, activa isScrollControlled.
  • Non abuses dos bottom sheets fixos: poden restar espazo ao contido.
  • O modal é máis natural para interaccións temporais.

🧭 A SnackBar: mensaxes temporais na parte inferior da pantalla #

A SnackBar é un dos mecanismos máis sinxelos e efectivos para mostrar mensaxes informativas ao usuario nunha app Flutter.
Aparece de forma temporal na parte inferior da pantalla e desaparece automaticamente tras uns segundos.

Úsase para:

  • Informar do resultado dunha acción (gardado, borrado…)
  • Mostrar erros rápidos
  • Dar feedback inmediato sen interromper o fluxo da app
  • Ofrecer accións rápidas (ex: Desfacer)

🔹 Como se mostra unha SnackBar? #

As SnackBar non son unha propiedade directa do Scaffold.
Para amosalas, Flutter usa o ScaffoldMessenger, que é o encargado de xestionalas.

A forma máis simple:

ScaffoldMessenger.of(context).showSnackBar(
  const SnackBar(
    content: Text('Isto é unha SnackBar!'),
  ),
);

🔍 Estrutura dunha SnackBar #

Unha SnackBar adoita incluír:

  • content → texto principal
  • action → botón opcional
  • duration → tempo que permanece visible
  • behavior → comportamento (fixo ou flotante)

📌 Exemplo básico usando un botón #

ElevatedButton(
  onPressed: () {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        content: Text('Operación realizada correctamente!'),
      ),
    );
  },
  child: const Text('Mostrar SnackBar'),
)

⭐ Exemplo cunha acción (botón dentro da SnackBar) #

ScaffoldMessenger.of(context).showSnackBar(
  SnackBar(
    content: const Text('Elemento eliminado'),
    action: SnackBarAction(
      label: 'Desfacer',
      onPressed: () {
        // Lóxica para desfacer
      },
    ),
  ),
);

🎨 Personalizar unha SnackBar #

SnackBar(
  content: const Text('Aviso importante'),
  duration: const Duration(seconds: 3),
  backgroundColor: Colors.deepPurple,
  behavior: SnackBarBehavior.floating,
  margin: const EdgeInsets.all(16),
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(12),
  ),
)

🧪 App simple de exemplo #

🔗 Ver o código en DartPad

📎 Consellos prácticos #

  • Non uses SnackBars para mensaxes moi longas → mellor un diálogo.
  • Non mostres SnackBars repetidamente ao navegar entre pantallas.

📝 Resumo #

CompoñentePara que serve
SnackBarMensaxe temporal que aparece abaixo ou flotando
ScaffoldMessengerControla e amosa SnackBars en pantalla
SnackBarActionEngade botóns rápidos como “Desfacer”

📚 Recursos oficiais #

Exemplo práctico: Scaffold completo #

Imos crear unha aplicación que mostre un Scaffold co visto nesta sección.

🔗 Ver o código en DartPad