My understanding is that in Flutter, the only time the screen will update is when a value it uses is changed with setState()
.
Here's my general situation: I have a main screen that dynamically generates tiles containing information pulled from SharedPreferences. The tiles can be edited by clicking a button on the tile which pulls up a dialog box where fields can be entered to update the values in sharedpreferences. After a lot of work, I have this part working. Unfortunately, the screen does not update after the change is made (I have to restart the app or whatever to see the change).
I'm not really sure what to do here, I recall reading something about InheritedWidgets in flutter, but not sure if that is applicable here. I tried just adding setState(() {})
at the end of the logic in onPressed()
in the dialog box, to no avail.
Here is the onPressed
logic within the dialog box Widget
onPressed: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var paoData = (json.decode(prefs.getString(paoKey)) as List).map((i) => PAOData.fromJson(i)).toList();
int currIndex = int.parse(widget.paoData.digits);
PAOData updatedPAOEntry = paoData[currIndex];
if (personTextController.text != '') {
print('saving person');
updatedPAOEntry.person = personTextController.text;
personTextController.text = '';
}
if (actionTextController.text != '') {
print('saving action');
updatedPAOEntry.action = actionTextController.text;
actionTextController.text = '';
}
if (objectTextController.text != '') {
print('saving object');
updatedPAOEntry.object = objectTextController.text;
objectTextController.text = '';
}
print('will update $currIndex to: ${updatedPAOEntry.person} | ${updatedPAOEntry.action} | ${updatedPAOEntry.object}');
paoData[currIndex] = updatedPAOEntry;
prefs.setString(paoKey, json.encode(paoData));
setState(() {
paoData = paoData;
});
Navigator.of(context).pop();
},
Separately, in the main page:
List<PAOView> getPAOViews () {
List<PAOView> paoViews = [];
if (paoData != null) {
for (int i = 0; i < paoData.length; i++) {
PAOView paoView = PAOView(paoData: PAOData(paoData[i].digits,
paoData[i].person, paoData[i].action, paoData[i].object,
paoData[i].familiarity));
paoViews.add(paoView);
}
}
return paoViews;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('MEM++ Homepage'),
),
body: Center(
child: ListView(
children: getPAOViews(),
)
),
);
}
Full PAOView:
class PAOView extends StatefulWidget {
final PAOData paoData;
PAOView({this.paoData});
@override
_PAOViewState createState() => _PAOViewState();
}
class _PAOViewState extends State<PAOView> {
final personTextController = TextEditingController();
final actionTextController = TextEditingController();
final objectTextController = TextEditingController();
SharedPreferences sharedPreferences;
String paoKey = 'pao';
@override
void dispose() {
// Clean up the controller when the widget is disposed.
personTextController.dispose();
actionTextController.dispose();
objectTextController.dispose();
super.dispose();
}
Widget build(BuildContext context) {
Dialog dialog = Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
//this right here
child: Container(
height: 350.0,
width: 300.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Person'),
),
Container(
padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
child: TextField(
textAlign: TextAlign.center,
controller: personTextController,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(5),
border: OutlineInputBorder(),
hintText: '${widget.paoData.person}',
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Action'),
),
Container(
padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
child: TextField(
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(5),
border: OutlineInputBorder(),
hintText: '${widget.paoData.action}'),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Object'),
),
Container(
padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
child: TextField(
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(5),
border: OutlineInputBorder(),
hintText: '${widget.paoData.object}'),
),
),
Container(
width: 5,
height: 10,
),
FlatButton(
onPressed: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var paoData = (json.decode(prefs.getString(paoKey)) as List).map((i) => PAOData.fromJson(i)).toList();
int currIndex = int.parse(widget.paoData.digits);
PAOData updatedPAOEntry = paoData[currIndex];
if (personTextController.text != '') {
print('saving person');
updatedPAOEntry.person = personTextController.text;
personTextController.text = '';
}
if (actionTextController.text != '') {
print('saving action');
updatedPAOEntry.action = actionTextController.text;
actionTextController.text = '';
}
if (objectTextController.text != '') {
print('saving object');
updatedPAOEntry.object = objectTextController.text;
objectTextController.text = '';
}
print('will update $currIndex to: ${updatedPAOEntry.person} | ${updatedPAOEntry.action} | ${updatedPAOEntry.object}');
paoData[currIndex] = updatedPAOEntry;
prefs.setString(paoKey, json.encode(paoData));
setState(() {
paoData = paoData;
});
Navigator.of(context).pop();
},
child: Container(
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.all(Radius.circular(5)),
),
padding: EdgeInsets.fromLTRB(20, 5, 20, 5),
child: Text(
'Save',
style: TextStyle(fontSize: 18.0),
),
))
],
),
),
);
return Center(
child: Card(
child: Stack(
children: <Widget>[
// TODO add overlay of familiarity somewhere
ListTile(
leading: Text(
'${widget.paoData.digits}',
style: TextStyle(fontSize: 26),
),
title: Text('${widget.paoData.person}',
style: TextStyle(fontSize: 20)),
subtitle:
Text('${widget.paoData.action} • ${widget.paoData.object}',
style: TextStyle(fontSize: 16),),
trailing: FlatButton(
child: Text('Edit', style: TextStyle(color: Colors.cyan)),
onPressed: () {
showDialog(context: context, child: dialog);
}),
),
],
)),
);
}
}