Lezione 7: NavigationBar, Tabs e Drawer
Obiettivi
Section titled “Obiettivi”- Usare NavigationBar per la navigazione a tab inferiori
- Creare un menu laterale con NavigationDrawer
- Combinare AppBar, NavigationBar e Drawer
1. NavigationBar (Bottom Navigation)
Section titled “1. NavigationBar (Bottom Navigation)”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à di NavigationBar
Section titled “Proprietà di NavigationBar”| Proprietà | Descrizione |
|---|---|
destinations | Lista di NavigationDestination |
selected_index | Indice del tab selezionato |
on_change | Funzione chiamata quando si cambia tab |
bgcolor | Colore di sfondo |
label_behavior | NavigationBarLabelBehavior.ALWAYS_SHOW / ONLY_SELECTED |
Personalizzare NavigationDestination
Section titled “Personalizzare NavigationDestination”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)3. NavigationDrawer (Menu laterale)
Section titled “3. NavigationDrawer (Menu laterale)”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)4. AppBar con Drawer integrato
Section titled “4. AppBar con Drawer integrato”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)5. Tabella riassuntiva
Section titled “5. Tabella riassuntiva”| Componente | Posizione | Uso tipico |
|---|---|---|
NavigationBar | In basso | 3-5 sezioni principali |
NavigationDrawer | Laterale (sinistra) | Menu esteso, impostazioni |
AppBar | In alto | Titolo, azioni, back button |
6. Esercizio autonomo
Section titled “6. Esercizio autonomo”🎯 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
NavigationBarcon 3 tab - Usa
AppBarcon 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())
Suggerimenti
Section titled “Suggerimenti”- 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”
Output atteso
Section titled “Output atteso”┌──────────────────────────┐│ ← Rubrica │ ← AppBar│ ││ 👤 Mario Rossi ││ 📞 345 1234567 ││ ─────────────────────── ││ 👤 Sofia Bianchi ││ 📞 345 7654321 ││ ─────────────────────── ││ 👤 Luca Verdi ││ 📞 345 9876543 ││ ││ [Contatti] [Aggiungi] [Info] │ ← NavigationBar└──────────────────────────┘