5.1 KiB
file lib/widgets/common/dialogs/miui_safe_dialog.dart import 'package:aves/widgets/common/dialogs/miu>
Perfetto Fabio — ora che il tuo primo dialog MIUI‑safe funziona, ti preparo una guida completa, chiara e salvabile, che puoi applicare a qualsiasi dialog di Aves (o di qualunque app Flutter) per renderlo completamente MIUI‑proof.
È una guida pratica, con pattern, checklist e snippet pronti da incollare.
⭐ GUIDA COMPLETA — Come rendere qualsiasi dialog Flutter MIUI‑safe
🎯 Obiettivo Evitare i problemi tipici di MIUI:
- tastiera lenta o che non si apre
- impossibilità di scrivere
- animazioni IME infinite
- callback pendenti che esplodono
- errori tipo:
- 'attached': is not true
- '_elements.contains(element)': is not true
- '_dependents.isEmpty': is not true
🧩 1. Usa sempre il wrapper globale
Invece di:
dart showDialog(...)
usa:
dart showMiuiSafeDialog(...)
Questo evita problemi di lifecycle quando MIUI distrugge la Activity.
🧩 2. Mai usare autofocus: true nei dialog
MIUI odia autofocus: true nei dialog.
Sostituisci sempre con:
dart autofocus: false
🧩 3. Mai usare addPostFrameCallback per il focus
Questo crea callback pendenti che MIUI può far esplodere.
Sostituisci con:
dart Future.microtask(() async { if (!context.mounted) return; await Future.delayed(const Duration(milliseconds: 30)); // MIUI-safe if (!context.mounted) return; FocusScope.of(context).requestFocus(focusNode); });
🧩 4. Sempre controllare context.mounted
Ogni volta che fai:
- Navigator.pop
- FocusScope.of(context)
- setState
- requestFocus
aggiungi:
dart if (!context.mounted) return;
MIUI distrugge la Activity mentre il dialog è aperto → senza questa guardia, crash.
🧩 5. Mai usare FocusManager.instance.primaryFocus?.unfocus()
MIUI applica una animazione IME di 600 ms quando fai unfocus().
Se devi chiudere la tastiera:
dart FocusScope.of(context).unfocus();
oppure non farlo affatto (meglio).
🧩 6. Usa sempre un FocusNode dedicato
Per ogni TextField in un dialog:
dart final focusNode = FocusNode();
e poi:
dart focusNode.dispose();
dopo il dialog.
🧩 7. Usa sempre un delay minimo per MIUI
MIUI ha bisogno di ~30 ms per agganciare il nuovo ViewRootImpl.
Quindi:
dart await Future.delayed(const Duration(milliseconds: 30));
🧩 8. Usa i tuoi dialog MIUI‑safe
Hai già:
- MiuiSafeTextDialog
- showMiuiSafeDialog
Puoi creare altri tipi:
✔ Conferma
`dart class MiuiSafeConfirmDialog extends StatelessWidget { final String title; final String message;
const MiuiSafeConfirmDialog({ super.key, required this.title, required this.message, });
@override Widget build(BuildContext context) { return AlertDialog( title: Text(title), content: Text(message), actions: [ TextButton( onPressed: () { if (!context.mounted) return; Navigator.of(context).pop(false); }, child: const Text('Annulla'), ), TextButton( onPressed: () { if (!context.mounted) return; Navigator.of(context).pop(true); }, child: const Text('OK'), ), ], ); } } `
✔ Lista di opzioni
`dart class MiuiSafeListDialog extends StatelessWidget { final String title; final List items; final String Function(T) label;
const MiuiSafeListDialog({ super.key, required this.title, required this.items, required this.label, });
@override Widget build(BuildContext context) { return AlertDialog( title: Text(title), content: SizedBox( width: double.maxFinite, child: ListView.builder( shrinkWrap: true, itemCount: items.length, itemBuilder: (_, i) { final item = items[i]; return ListTile( title: Text(label(item)), onTap: () { if (!context.mounted) return; Navigator.of(context).pop(item); }, ); }, ), ), ); } } `
🧩 9. Checklist finale (salvala!)
✔ Per ogni dialog:
- usare showMiuiSafeDialog
- niente autofocus: true
- niente addPostFrameCallback
- usare Future.microtask + delay MIUI
- controllare context.mounted
- evitare unfocus() con delay
- usare FocusNode dedicato
- evitare animazioni IME
- evitare callback pendenti
🧩 10. Esempio completo (da salvare)
Prima (Flutter normale)
dart showDialog( context: context, builder: (_) => AlertDialog( content: TextField(autofocus: true), ), );
Dopo (MIUI‑safe)
dart showMiuiSafeDialog( context: context, builder: (ctx) => MiuiSafeTextDialog( title: 'Titolo', label: 'Campo', hint: 'Scrivi qui', initialText: '', ), );
🎉 Risultato
Con questa guida puoi convertire qualsiasi dialog di Aves in versione MIUI‑safe:
- tastiera istantanea
- input immediato
- nessun lag
- nessun crash
- nessun assert del framework
- nessun callback pendente
- nessuna animazione IME infinita