I've got a simple dialog in my app to create a user profile. It has an Image you can change and a TextFormField for entering the name. But when I tap on the TextFormField, it rebuilds the dialog and resets the image variable. How can i fix this?
Here's the basic code (I get the issue with this code as well):
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter/painting.dart';
import 'dart:io';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Issue demo'),
),
body: Center(
child: RaisedButton(
onPressed: () {
showDialog(context: context, builder: (context) => MyDialog());
},
child: Text('show dialog'),
),
),
);
}
}
class MyDialog extends StatefulWidget {
File image;
String name;
MyDialog({this.image, this.name});
@override
_MyDialogState createState() => _MyDialogState();
}
class _MyDialogState extends State<MyDialog> {
final _formKey = new GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return SimpleDialog(
children: <Widget>[
ListTile(
leading: Icon(Icons.add_circle),
title: Text('new person'),
),
FittedBox(
fit: BoxFit.fitWidth,
child: FlatButton(
shape: CircleBorder(),
child: CircleAvatar(
backgroundImage:
(widget.image != null) ? FileImage(widget.image) : null,
child: (widget.image == null) ? Icon(Icons.person) : null),
onPressed: () async {
File newImage =
await ImagePicker.pickImage(source: ImageSource.camera);
if (newImage != null) {
imageCache.clear();
setState(() {
widget.image = newImage;
});
}
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
key: _formKey,
child: TextFormField(
initialValue: widget.name,
maxLines: 1,
keyboardType: TextInputType.text,
autofocus: false,
onSaved: (value) {
setState(() {
widget.name = value;
print(value);
});
},
decoration: new InputDecoration(
icon: Icon(Icons.perm_identity),
hintText: 'Name',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)),
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FlatButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('Save'),
onPressed: () {
Navigator.of(context).pop();
}),
],
),
],
);
}
}
I've solved it now! My answer is below, though I have no idea why it solved the problem! :)
asked Sep 9, 2019 at 9:09
JakesMD
2,2764 gold badges25 silver badges52 bronze badges
-
I just had the same issue, but the actual issue was somewhere higher in the hierarchy. For me it was a FutureBuilder that got recreated, but it probably could have been anything elsedumazy– dumazy2019年09月09日 09:13:29 +00:00Commented Sep 9, 2019 at 9:13
-
Which dialog are you using, can you share some codes?CopsOnRoad– CopsOnRoad2019年09月09日 10:01:46 +00:00Commented Sep 9, 2019 at 10:01
-
Did you find the reason of solution?Can Karabag– Can Karabag2019年09月09日 12:06:36 +00:00Commented Sep 9, 2019 at 12:06
-
No, I'm afraid. I solved the problem by accident!JakesMD– JakesMD2019年09月09日 12:22:20 +00:00Commented Sep 9, 2019 at 12:22
1 Answer 1
It's ok! I've solved it!!!!!
I simply moved the image variable to _MyDialogState and now it works!!!! Can anyone tell me why it works??
class MyDialog extends StatefulWidget {
File image;
String name;
MyDialog({this.image, this.name});
@override
_MyDialogState createState() => _MyDialogState();
}
class _MyDialogState extends State<MyDialog> {
final _formKey = new GlobalKey<FormState>();
String name;
File image;
@override
void initState() {
super.initState();
image = widget.image;
name = widget.name;
}
@override
Widget build(BuildContext context) {
return SimpleDialog(
children: <Widget>[
ListTile(
leading: Icon(Icons.add_circle),
title: Text('new person'),
),
FittedBox(
fit: BoxFit.fitWidth,
child: FlatButton(
shape: CircleBorder(),
child: CircleAvatar(
backgroundImage:
(image != null) ? FileImage(image) : null,
child: (image == null) ? Icon(Icons.person) : null),
onPressed: () async {
File newImage =
await ImagePicker.pickImage(source: ImageSource.camera);
if (newImage != null) {
imageCache.clear();
setState(() {
image = newImage;
});
}
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
key: _formKey,
child: TextFormField(
initialValue: name,
maxLines: 1,
keyboardType: TextInputType.text,
autofocus: false,
onSaved: (value) {
setState(() {
name = value;
print(value);
});
},
decoration: new InputDecoration(
icon: Icon(Icons.perm_identity),
hintText: 'Name',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)),
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FlatButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('Save'),
onPressed: () {
Navigator.of(context).pop();
}),
],
),
],
);
}
}
answered Sep 9, 2019 at 11:13
JakesMD
2,2764 gold badges25 silver badges52 bronze badges
Sign up to request clarification or add additional context in comments.
Comments
lang-dart