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

281 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<T> extends StatelessWidget {
final String title;
final List<T> 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