Aves_mio0.88/dialogMIUI.md
2026-10-03 12:51:15 +02:00

5.1 KiB
Raw Permalink Blame History

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