2

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
4
  • 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 else Commented Sep 9, 2019 at 9:13
  • Which dialog are you using, can you share some codes? Commented Sep 9, 2019 at 10:01
  • Did you find the reason of solution? Commented Sep 9, 2019 at 12:06
  • No, I'm afraid. I solved the problem by accident! Commented Sep 9, 2019 at 12:22

1 Answer 1

2

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.