Skip to content

Lezione 7: NavigationBar, Tabs e Drawer

  • Usare NavigationBar per la navigazione a tab inferiori
  • Creare un menu laterale con NavigationDrawer
  • Combinare AppBar, NavigationBar e Drawer

NavigationBar crea una barra di navigazione nella parte inferiore della schermata, tipica delle app mobile.

import flet as ft
def main(page: ft.Page):
page.title = "Tab Navigation"
page.padding = 10
contenuto = ft.Column([], expand=True)
def cambia_tab(e):
contenuto.controls.clear()
if nav_bar.selected_index == 0:
contenuto.controls.append(ft.Text("🏠 Home", size=30, weight="bold"))
contenuto.controls.append(ft.Text("Benvenuto nella home!"))
elif nav_bar.selected_index == 1:
contenuto.controls.append(ft.Text("🔍 Cerca", size=30, weight="bold"))
contenuto.controls.append(ft.TextField(hint_text="Cosa cerchi?", width=300))
elif nav_bar.selected_index == 2:
contenuto.controls.append(ft.Text("⚙️ Impostazioni", size=30, weight="bold"))
contenuto.controls.append(ft.Text("Qui puoi configurare l'app."))
page.update()
nav_bar = ft.NavigationBar(
destinations=[
ft.NavigationDestination(icon=ft.icons.HOME, label="Home"),
ft.NavigationDestination(icon=ft.icons.SEARCH, label="Cerca"),
ft.NavigationDestination(icon=ft.icons.SETTINGS, label="Impostazioni"),
],
on_change=cambia_tab,
selected_index=0,
)
cambia_tab(None)
page.add(contenuto)
page.navigation_bar = nav_bar
page.update()
ft.app(target=main)
ProprietàDescrizione
destinationsLista di NavigationDestination
selected_indexIndice del tab selezionato
on_changeFunzione chiamata quando si cambia tab
bgcolorColore di sfondo
label_behaviorNavigationBarLabelBehavior.ALWAYS_SHOW / ONLY_SELECTED
ft.NavigationDestination(
icon=ft.icons.HOME, # Icona (non selezionato)
selected_icon=ft.icons.HOME_OUTLINED, # Icona (selezionato)
label="Home", # Etichetta
)

2. NavigationBar con View (navigazione integrata)

Section titled “2. NavigationBar con View (navigazione integrata)”

Usiamo NavigationBar dentro le View:

import flet as ft
def main(page: ft.Page):
page.title = "App con Tab + Navigazione"
def route_change(e):
page.views.clear()
# Schermata principale
page.views.append(
ft.View(
route="/",
navigation_bar=ft.NavigationBar(
destinations=[
ft.NavigationDestination(icon=ft.icons.HOME, label="Home"),
ft.NavigationDestination(icon=ft.icons.SEARCH, label="Cerca"),
ft.NavigationDestination(icon=ft.icons.PERSON, label="Profilo"),
],
on_change=lambda e: cambia_pagina(e),
selected_index=navigazione["tab"],
),
controls=[contenuto_principale],
)
)
page.update()
# Stato navigazione
navigazione = {"tab": 0}
contenuto_principale = ft.Column([], expand=True)
def cambia_pagina(e):
navigazione["tab"] = e.control.selected_index
aggiorna_contenuto()
page.update()
def aggiorna_contenuto():
contenuto_principale.controls.clear()
if navigazione["tab"] == 0:
contenuto_principale.controls.append(ft.Text("🏠 Home", size=28, weight="bold"))
contenuto_principale.controls.append(ft.ElevatedButton("Vai dettaglio", on_click=lambda _: page.go("/dettaglio")))
elif navigazione["tab"] == 1:
contenuto_principale.controls.append(ft.Text("🔍 Cerca", size=28, weight="bold"))
elif navigazione["tab"] == 2:
contenuto_principale.controls.append(ft.Text("👤 Profilo", size=28, weight="bold"))
page.on_route_change = route_change
aggiorna_contenuto()
page.go("/")
ft.app(target=main)

Il NavigationDrawer è il menu che scivola da sinistra, tipico delle app Android.

import flet as ft
def main(page: ft.Page):
page.title = "Drawer Navigation"
page.padding = 30
contenuto = ft.Column([], expand=True)
def chiudi_drawer(e):
page.drawer.open = False
page.update()
def seleziona(e, sezione):
contenuto.controls.clear()
contenuto.controls.append(ft.Text(sezione, size=30, weight="bold"))
chiudi_drawer(e)
page.update()
# Crea il drawer
page.drawer = ft.NavigationDrawer(
controls=[
ft.Container(height=12),
ft.NavigationDrawerDestination(
icon=ft.icons.HOME,
label="Home",
),
ft.Divider(thickness=2),
ft.NavigationDrawerDestination(
icon=ft.icons.PERSON,
label="Profilo",
),
ft.NavigationDrawerDestination(
icon=ft.icons.SETTINGS,
label="Impostazioni",
),
ft.NavigationDrawerDestination(
icon=ft.icons.INFO,
label="Informazioni",
),
],
on_change=lambda e: seleziona(e, ["Home", "Profilo", "Impostazioni", "Info"][e.control.selected_index]),
)
# Bottone per aprire drawer (di solito si mette nell'AppBar)
def apri_drawer(e):
page.drawer.open = True
page.update()
page.add(
ft.Row([
ft.IconButton(ft.icons.MENU, on_click=apri_drawer),
ft.Text("Menu", size=24, weight="bold"),
]),
contenuto,
)
# Contenuto iniziale
contenuto.controls.append(ft.Text("Home", size=30, weight="bold"))
ft.app(target=main)

Il pattern più comune: AppBar con icona hamburger che apre il drawer.

import flet as ft
def main(page: ft.Page):
page.title = "Drawer + AppBar"
page.padding = 0
def apri_drawer(e):
page.drawer.open = True
page.update()
def chiudi_drawer(e):
page.drawer.open = False
page.update()
def seleziona(e):
labels = ["Home", "Impostazioni", "Info"]
idx = e.control.selected_index
page.views[0].controls[0].value = labels[idx]
page.update()
chiudi_drawer(e)
page.drawer = ft.NavigationDrawer(
controls=[
ft.Container(
content=ft.Text("Menu", size=24, weight="bold"),
padding=ft.padding.all(20),
),
ft.Divider(),
ft.NavigationDrawerDestination(icon=ft.icons.HOME, label="Home"),
ft.NavigationDrawerDestination(icon=ft.icons.SETTINGS, label="Impostazioni"),
ft.NavigationDrawerDestination(icon=ft.icons.INFO, label="Info"),
],
on_change=seleziona,
)
page.add(
ft.View(
route="/",
appbar=ft.AppBar(
title=ft.Text("Home"),
leading=ft.IconButton(ft.icons.MENU, on_click=apri_drawer),
bgcolor=ft.colors.BLUE,
color=ft.colors.WHITE,
),
controls=[
ft.Container(
content=ft.Column([
ft.Text("Benvenuto!", size=28, weight="bold"),
ft.Text("Usa il menu per navigare."),
]),
padding=30,
)
],
)
)
page.update()
ft.app(target=main)

ComponentePosizioneUso tipico
NavigationBarIn basso3-5 sezioni principali
NavigationDrawerLaterale (sinistra)Menu esteso, impostazioni
AppBarIn altoTitolo, azioni, back button

🎯 Esercizio: “App Rubrica con Tab + Dettaglio”

Section titled “🎯 Esercizio: “App Rubrica con Tab + Dettaglio””

Crea un file rubrica_app.py che realizzi un’app rubricacon 3 tab:

Tab 1 — Contatti:

  • ListView con alcuni contatti predefiniti
  • Ogni contatto mostra: avatar (iniziale), nome, telefono

Tab 2 — Aggiungi:

  • Form per aggiungere un nuovo contatto (nome, telefono, email)
  • Bottone “Salva” che aggiunge alla lista del Tab 1

Tab 3 — Info:

  • Nome app, versione, sviluppatore
  • Crediti

Requisiti:

  • Usa NavigationBar con 3 tab
  • Usa AppBar con titolo che cambia in base al tab selezionato
  • I contatti devono essere persistenti nella sessione
  • Quando si clicca un contatto, naviga a una schermata di dettaglio (via page.go())
  • Usa una lista globale per memorizzare i contatti
  • Usa page.go("/dettaglio?id=NOME") per navigare al dettaglio
  • Nel dettaglio, mostra tutte le info del contatto e un bottone ”← Indietro”
┌──────────────────────────┐
│ ← Rubrica │ ← AppBar
│ │
│ 👤 Mario Rossi │
│ 📞 345 1234567 │
│ ─────────────────────── │
│ 👤 Sofia Bianchi │
│ 📞 345 7654321 │
│ ─────────────────────── │
│ 👤 Luca Verdi │
│ 📞 345 9876543 │
│ │
│ [Contatti] [Aggiungi] [Info] │ ← NavigationBar
└──────────────────────────┘