Lorsque j'utilise un widget TextField dans Flutter et que je fixe la valeur de la propriété autoFocus à true
import 'package:flutter/material.Dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: TextField(
autofocus: true,
),
),
);
}
}
flutter lance une erreur
I/flutter (31721): ══╡ EXCEPTION CAUGHT BY FOUNDATION LIBRARY ╞════════════════════════════════════════════════════════
I/flutter (31721): The following assertion was thrown while dispatching notifications for FocusNode:
I/flutter (31721): RenderBox was not laid out: RenderEditable#bf516 NEEDS-LAYOUT NEEDS-Paint
I/flutter (31721): 'package:flutter/src/rendering/box.Dart':
I/flutter (31721): Failed assertion: line 1687 pos 12: 'hasSize'
I/flutter (31721):
I/flutter (31721): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (31721): more information in this error message to help you determine and fix the underlying cause.
I/flutter (31721): In either case, please report this assertion by filing a bug on GitHub:
I/flutter (31721): https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter (31721):
I/flutter (31721): When the exception was thrown, this was the stack:
I/flutter (31721): #2 RenderBox.size
package:flutter/…/rendering/box.Dart:1687
I/flutter (31721): #3 EditableTextState._updateSizeAndTransform
package:flutter/…/widgets/editable_text.Dart:1729
I/flutter (31721): #4 EditableTextState._openInputConnection
package:flutter/…/widgets/editable_text.Dart:1415
I/flutter (31721): #5 EditableTextState._openOrCloseInputConnectionIfNeeded
package:flutter/…/widgets/editable_text.Dart:1441
I/flutter (31721): #6 EditableTextState._handleFocusChanged
package:flutter/…/widgets/editable_text.Dart:1707
I/flutter (31721): #7 ChangeNotifier.notifyListeners
package:flutter/…/foundation/change_notifier.Dart:206
I/flutter (31721): #8 FocusNode._notify
package:flutter/…/widgets/focus_manager.Dart:808
I/flutter (31721): #9 FocusManager._applyFocusChange
package:flutter/…/widgets/focus_manager.Dart:1401
I/flutter (31721): (elided 12 frames from class _AssertionError and package Dart:async)
I/flutter (31721):
I/flutter (31721): The FocusNode sending notification was:
I/flutter (31721): FocusNode#ce6fe
I/flutter (31721): ════════════════════════════════════════════════════════════════════════════════════════════════════
Pourquoi et comment puis-je résoudre ce problème.
ma version flottante:
[√] Flutter (Channel stable, v1.12.13 + hotfix.5, sur Microsoft Windows [Version 10.0.18362.535], locale en-US) [√] Android toolchain - développer pour Android appareils ( SDK Android version 29.0.2) [√] Android Studio (version 3.5) [√] VS Code (version 1.41.0) [√] Appareil connecté (1 disponible) • Aucun problème trouvé!
================================================== ======================
Ce problème existe même dans l'exemple officiel https://flutter.dev/docs/cookbook/forms/focus
Parce qu'avec la mise au point automatique, le clavier apparaît en premier mais le champ de texte n'existe toujours pas
Solution de contournement: utilisez FocusNode
et WidgetsBinding.instance.addPostFrameCallback
Lorsque TextField s'affiche, puis déplacez le focus sur ce TextField
extrait de code
@override
void initState(){
super.initState();
myFocusNode = FocusNode();
WidgetsBinding.instance.addPostFrameCallback((_){
FocusScope.of(context).requestFocus(myFocusNode);
});
}
code complet
import 'package:flutter/material.Dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
FocusNode myFocusNode;
@override
void initState(){
super.initState();
myFocusNode = FocusNode();
WidgetsBinding.instance.addPostFrameCallback((_){
FocusScope.of(context).requestFocus(myFocusNode);
});
}
@override
void dispose() {
// Clean up the focus node when the Form is disposed.
myFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: TextField(
//autofocus: true,
focusNode: myFocusNode,
),
),
);
}
}
Ce bug a été corrigé, mais pour l'instant, le correctif n'est pas dans le canal stable ( https://github.com/flutter/flutter/issues/52221 ). Si votre projet le permet, vous pouvez passer au canal de développement (> 1.15) et simplement utiliser la mise au point automatique.
Depuis la ligne de commande:
flutter channel dev
flutter upgrade
Reconstruisez votre projet et cela devrait fonctionner.