[{"data":1,"prerenderedAt":22},["ShallowReactive",2],{"articolo-gestire-i-temi-in-flutter-material-3-themeextension-e-dark-mode-dinamica":3,"comments-article-gestire-i-temi-in-flutter-material-3-themeextension-e-dark-mode-dinamica":21},{"id":4,"title":5,"slug":6,"excerpt":7,"body":8,"cover_image":9,"video_url":10,"status":11,"published_at":12,"meta_title":13,"meta_description":14,"category":15,"author":19},12,"Gestire i temi in Flutter: Material 3, ThemeExtension e dark mode dinamica","gestire-i-temi-in-flutter-material-3-themeextension-e-dark-mode-dinamica","Impara a costruire un sistema di temi robusto in Flutter con Material 3, a creare colori personalizzati con ThemeExtension e a gestire il passaggio tra tema chiaro e scuro in modo reattivo.","## Perché un buon sistema di temi è fondamentale\n\nUn'applicazione professionale deve garantire coerenza visiva, supporto al tema scuro e facilità di manutenzione. Flutter offre un sistema di theming potente, soprattutto dopo l'introduzione di **Material 3** (Material You), che ridefinisce il modo in cui colori, tipografia e componenti vengono gestiti.\n\nIn questo articolo vedremo come configurare Material 3, generare uno schema di colori coerente, estendere il tema con valori personalizzati tramite `ThemeExtension` e implementare un cambio di tema dinamico.\n\n## Abilitare Material 3\n\nDalle versioni recenti di Flutter, Material 3 è attivo per impostazione predefinita. Possiamo comunque configurarlo esplicitamente partendo da un colore seme (`seedColor`), dal quale Flutter genera l'intera palette armonica.\n\n```dart\nimport 'package:flutter\u002Fmaterial.dart';\n\nfinal ThemeData lightTheme = ThemeData(\n  useMaterial3: true,\n  colorScheme: ColorScheme.fromSeed(\n    seedColor: const Color(0xFF6750A4),\n    brightness: Brightness.light,\n  ),\n);\n\nfinal ThemeData darkTheme = ThemeData(\n  useMaterial3: true,\n  colorScheme: ColorScheme.fromSeed(\n    seedColor: const Color(0xFF6750A4),\n    brightness: Brightness.dark,\n  ),\n);\n```\n\nUsando lo stesso `seedColor` per entrambe le luminosità otteniamo coerenza cromatica tra tema chiaro e scuro.\n\n## Applicare i temi a MaterialApp\n\nL'oggetto `MaterialApp` accetta `theme`, `darkTheme` e `themeMode`. Quest'ultimo determina quale tema usare: `system` segue le impostazioni del dispositivo, `light` e `dark` forzano una modalità specifica.\n\n```dart\nMaterialApp(\n  theme: lightTheme,\n  darkTheme: darkTheme,\n  themeMode: ThemeMode.system,\n  home: const HomePage(),\n);\n```\n\n## Personalizzare la tipografia e i componenti\n\nOltre ai colori, possiamo definire stili di testo e personalizzare i singoli widget tramite i rispettivi `Theme` data.\n\n```dart\nThemeData(\n  useMaterial3: true,\n  colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),\n  textTheme: const TextTheme(\n    titleLarge: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),\n    bodyMedium: TextStyle(fontSize: 16, height: 1.4),\n  ),\n  filledButtonTheme: FilledButtonThemeData(\n    style: FilledButton.styleFrom(\n      shape: RoundedRectangleBorder(\n        borderRadius: BorderRadius.circular(12),\n      ),\n    ),\n  ),\n);\n```\n\n## Estendere il tema con ThemeExtension\n\nIl `ColorScheme` di Material 3 copre molti casi, ma spesso un'app ha bisogno di colori semantici aggiuntivi (es. il verde \"successo\", il giallo \"avviso\") non previsti dallo schema standard. La soluzione idiomatica è `ThemeExtension`.\n\n```dart\nimport 'package:flutter\u002Fmaterial.dart';\n\nclass AppColors extends ThemeExtension\u003CAppColors> {\n  final Color success;\n  final Color warning;\n\n  const AppColors({required this.success, required this.warning});\n\n  @override\n  AppColors copyWith({Color? success, Color? warning}) {\n    return AppColors(\n      success: success ?? this.success,\n      warning: warning ?? this.warning,\n    );\n  }\n\n  @override\n  AppColors lerp(ThemeExtension\u003CAppColors>? other, double t) {\n    if (other is! AppColors) return this;\n    return AppColors(\n      success: Color.lerp(success, other.success, t)!,\n      warning: Color.lerp(warning, other.warning, t)!,\n    );\n  }\n}\n```\n\nIl metodo `lerp` garantisce transizioni animate fluide quando si cambia tema. Registriamo l'estensione nel `ThemeData`:\n\n```dart\nfinal lightTheme = ThemeData(\n  useMaterial3: true,\n  colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),\n  extensions: const [\n    AppColors(success: Color(0xFF2E7D32), warning: Color(0xFFF9A825)),\n  ],\n);\n```\n\nE la recuperiamo nei widget tramite il `Theme`:\n\n```dart\nWidget build(BuildContext context) {\n  final appColors = Theme.of(context).extension\u003CAppColors>()!;\n  return Container(color: appColors.success);\n}\n```\n\n## Cambio di tema dinamico\n\nPer permettere all'utente di scegliere il tema, possiamo gestire lo stato del `themeMode`. Ecco un esempio semplice con `ValueNotifier`, facilmente sostituibile con il gestore di stato che preferite.\n\n```dart\nclass ThemeController {\n  static final themeMode = ValueNotifier\u003CThemeMode>(ThemeMode.system);\n\n  static void toggle() {\n    themeMode.value = themeMode.value == ThemeMode.dark\n        ? ThemeMode.light\n        : ThemeMode.dark;\n  }\n}\n```\n\n```dart\nValueListenableBuilder\u003CThemeMode>(\n  valueListenable: ThemeController.themeMode,\n  builder: (context, mode, _) {\n    return MaterialApp(\n      theme: lightTheme,\n      darkTheme: darkTheme,\n      themeMode: mode,\n      home: const HomePage(),\n    );\n  },\n);\n```\n\nPer rendere la scelta persistente tra una sessione e l'altra, basta salvare il valore con `shared_preferences` e ricaricarlo all'avvio.\n\n## Best practice\n\n- **Usa il ColorScheme**: evita colori hardcoded nei widget, accedi sempre a `Theme.of(context).colorScheme` per garantire il corretto adattamento alla dark mode.\n- **Centralizza il tema**: definisci i temi in un unico file, così da mantenere coerenza e facilitare modifiche future.\n- **Sfrutta ThemeExtension**: per ogni valore di design ricorrente non coperto dallo schema standard.\n- **Testa entrambe le modalità**: controlla sempre il contrasto e la leggibilità sia in chiaro che in scuro.\n\n## Conclusione\n\nMaterial 3 rende il theming in Flutter più espressivo e coerente. Combinando lo schema generato dal `seedColor`, le personalizzazioni dei componenti e la flessibilità di `ThemeExtension`, è possibile costruire un design system scalabile e pronto per la dark mode dinamica. Un investimento iniziale che ripaga in manutenibilità e qualità dell'esperienza utente.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Farticles\u002Fda584d62-0c7e-4d09-b0a1-8b3c16f6186a.jpg",null,"published","2026-06-15T04:00:36+00:00","Temi in Flutter con Material 3 e ThemeExtension","Guida pratica al theming in Flutter: Material 3, ColorScheme da seedColor, ThemeExtension per colori personalizzati e gestione della dark mode dinamica.",{"id":16,"name":17,"slug":18},1,"Guide","guide",{"id":16,"name":20},"Flutter Bot",[],1781680691414]