Flutter Menús
Revisión del 17:35 10 nov 2025 de Angelfg (discusión | contribuciones)
Sumario
Intruducción
- Tenemos diferentes tipos de menús.
- Dentro del Scaffold ya podemos emplear un Drawer Menu y opciones de menú en la AppBar que incorpora.
Menús en la Appbar
- Ya lo vimos anteriormente.
- En la Appbar tenemos la propiedad actions que espera recibir un conjunto de widget que se visualizarán en la Appbar. Normalmente se emplea para visualizar las opciones de menú.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'IconButton en AppBar',
home: Scaffold(
appBar: AppBar(
title: Text('Demo IconButton'),
actions: [
IconButton(
icon: Icon(Icons.search),
tooltip: 'Buscar',
onPressed: () {
// Aquí va la acción al pulsar el botón
print('IconButton presionado');
},
),
IconButton(
icon: Icon(Icons.settings),
tooltip: 'Configuración',
onPressed: () {
print('Configuración presionada');
},
),
],
),
body: Center(
child: Text('Cuerpo de la app'),
),
),
);
}
}
Empleando PopupMenuBotton
- Más información en https://api.flutter.dev/flutter/material/PopupMenuButton-class.html
- Es el clásico menú que aparece al pulsar sobre un icono. Normalmente lo pondremos en la seccion de actions del Scaffold cuando tengamos tengamos opciones de menú que no quepan en el espacio libre.
AppBar(
centerTitle: true,
title: Text("App Dropdown Menu"),
actions: [
//list if widget in appbar actions
PopupMenuButton(
icon: Icon(Icons.menu), //don't specify icon if you want 3 dot menu
color: Colors.blue,
itemBuilder: (context) => [
PopupMenuItem<int>(
value: 0,
child: Text("Setting",style: TextStyle(color: Colors.white),),
),
],
onSelected: (item) => {print(item)},
),
],
Drawer
- Es en menú que aparece lateralmente al desplazar el dedo en el teléfono desde la parte lateral-izquierda a la derecha.
- Más información:
- Ejemplo de uso:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
// Clase principal de la app
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Drawer en Clase Separada',
home: Scaffold(
appBar: AppBar(
title: Text('Drawer Separado'),
),
drawer: MyDrawer(), // Llamamos al Drawer definido en otra clase
body: Center(
child: Text('Cuerpo de la app'),
),
),
);
}
}
// Clase separada para el Drawer
class MyDrawer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(
'Encabezado del Drawer',
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Inicio'),
onTap: () {
Navigator.pop(context);
print('Inicio presionado');
},
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Configuración'),
onTap: () {
Navigator.pop(context);
print('Configuración presionada');
},
),
ListTile(
leading: Icon(Icons.logout),
title: Text('Cerrar sesión'),
onTap: () {
Navigator.pop(context);
print('Cerrar sesión presionado');
},
),
],
),
);
}
}
Menús Contextuales
- Permiten crear un menú contextual en cualquier parte de la pantalla.
- Es necesario determinar el tamaño y punto donde va a aparecer el menú.
- Más información: https://api.flutter.dev/flutter/material/showMenu.html
- Ejemplo de uso:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Menu sobre Container',
home: Scaffold(
appBar: AppBar(title: Text('showMenu sobre Container')),
body: Center(
child: MenuContainer(),
),
),
);
}
}
class MenuContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (details) {
// Obtenemos el RenderBox del overlay
final RenderBox overlay =
Overlay.of(context).context.findRenderObject() as RenderBox;
// Mostramos el menú sobre la posición del tap
showMenu(
context: context,
position: RelativeRect.fromRect(
details.globalPosition & Size(100, 100), // Rect del Container
Offset.zero & overlay.size, // Referencia: pantalla completa
),
items: [
PopupMenuItem(value: 'op1', child: Text('Opción 1')),
PopupMenuItem(value: 'op2', child: Text('Opción 2')),
PopupMenuItem(value: 'op3', child: Text('Opción 3')),
],
).then((value) {
if (value != null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Seleccionaste: $value')),
);
}
});
},
child: Container(
width: 100,
height: 100,
color: Colors.blue,
alignment: Alignment.center,
child: Text(
'Toca aquí',
style: TextStyle(color: Colors.white),
),
),
);
}
}
Enlace a la página principal de la UD5
Enlace a la página principal del curso
-- Ángel D. Fernández González -- (2021).