I'm developping a Flutter App that needed to have a form. So when the user open the app, a Splash Screen appear before the form that have the following code :
import 'package:flutter/material.dart';
import '../model/User.dart';
import './FileManager.dart';
import './MyListPage.dart';
class UserLoader extends StatefulWidget {
@override
_UserLoaderState createState() => new _UserLoaderState();
}
class _UserLoaderState extends State<UserLoader> {
final userFileName = "user_infos.txt";
User _user;
@override
Widget build(BuildContext context) {
print("build UserLoader");
final _formKey = new GlobalKey<FormState>();
final _firstNameController = new TextEditingController();
final _lastNameController = new TextEditingController();
final _emailController = new TextEditingController();
final _phoneController = new TextEditingController();
return new Scaffold(
appBar: new AppBar(
title: new Text("Informations"),
actions: <Widget>[
new IconButton(
icon: const Icon(Icons.save),
onPressed: () {
_user = _onFormValidate(
_formKey.currentState,
_firstNameController.text,
_lastNameController.text,
_emailController.text,
_phoneController.text);
})
],
),
body: new Center(
child: new SingleChildScrollView(
child: new Form(
key: _formKey,
child: new Column(children: <Widget>[
new ListTile(
leading: const Icon(Icons.person),
title: new TextFormField(
decoration: new InputDecoration(
hintText: "Prénom",
),
keyboardType: TextInputType.text,
controller: _firstNameController,
validator: _validateName,
),
),
new ListTile(
leading: const Icon(Icons.person),
title: new TextFormField(
decoration: new InputDecoration(
hintText: "Nom",
),
keyboardType: TextInputType.text,
controller: _lastNameController,
validator: _validateName,
),
),
Etc, etc ...
However when i tap the TextField, the keyboard appear and close immediately and all the component is rebuild. So it is impossible for me to complete the form..
Can someone have a solution please? Thanks in advance !
The solution is to pass a new Key to WidgetB every time we need it to be rebuilt: WidgetA will see that WidgetB has changed and will rebuild it when setState is called. In other words, whenever a stateful widget's Key property changes, calling setState on its parent will force a rebuild of the stateful widget.
When the instance of a widget stays the same; Flutter purposefully won't rebuild children. It implies that you can cache parts of your widget tree to prevent unnecessary rebuilds. Thanks to that const keyword, the instance of DecoratedBox will stay the same even if build were called hundreds of times.
The build method is called any time you call setState , your widget's dependencies update, or any of the parent widgets are rebuilt (when setState is called inside of those). Your widget will depend on any InheritedWidget you use, e.g. Theme. of(context) , MediaQuery. of(context) etc.
You haven't given us the entire code for this, so I don't know what the context is.
One pitfall I myself have fallen into (and might be affecting you, as I gather from your description) is having a stateful widget nested inside another stateful widget.
For instance,
class Parent extends StatefulWidget {
@override
ParentState createState() => ParentState();
(...)
}
class ParentState extends State<Parent> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Child(),
);
}
(...)
}
class Child extends StatefulWidget {
@override
ChildState createState() => ChildState();
(...)
}
class ChildState extends State<Child> {
@override
Widget build(BuildContext context) {
return TextField(...);
}
(...)
}
The problem here is that a rebuild of Parent means that ParentState().build()
is run, and a new Child
instance is created, with a new ChildState
object. Which resets everything.
Try not recreating ChildWidget, but instead saving it on ParentState, like so:
class Parent extends StatefulWidget {
@override
ParentState createState() => ParentState();
(...)
}
class ParentState extends State<Parent> {
Child _child;
@override
void initState() {
_child = Child();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _child,
);
}
(...)
}
// The rest remains the same
Edit: You just need to remember that, if your widget tree is a bit more complex, you may need to 1) pass a callback from the Parent to notify of state changes, and 2) not forget to also call setState() on the Child.
you just need make a new class and import that on your target class that seen problem. for example :
I usually create a class like this :
class MiddleWare
{
static MiddleWare shared = MiddleWare();
_MiddleWare(){}
String myText = "my Text";
// every variables should be here...
}
and
import "MiddleWare.dart";
class myclass extends StatefulWidget {
@override
_myclassState createState() => _myclassState();
}
class _myclassState extends State<myclass> {
@override
Widget build(BuildContext context) {
return Container(child: Text(MiddleWare.shared.myText));
}
}
that's it.
hi dont use Scaffold key i.e
Scaffold (
...
key: _scaffoldKey, //remove this
...
)
on the page and do a complete page rebuild (not hot reload), and you should be fine worked for me tho!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With