Question
Flutter: AutomaticKeepAliveClientMixin is not working with BottomNavigationBar
I have page called AddPatientView with BottomNavigationBar containing AddPatientInfo and AddPatientImages pages. All of these three are Stateful widgets.
By default the AddPatientInfo opens up which has bunch of TextFields (to enter patient info), in the AddPatientImages page the user can add Images.
The problem is if I fill the TextFields on AddPatientInfo then go to AddPatientImages and then go back, all the TextFields are empty. Rightfully so since the entire widget tree gets rebuild and I loose all my filled in data.
So I am implementing AutomaticKeepAliveClientMixin
so the state is maintained even if the tab is changed. But it does not seems to work:
Here is my code:
AddPatientView (the parent)
class AddPatientView extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _AddPatientViewState();
}
}
class _AddPatientViewState extends State<AddPatientView> {
int _currentIndex = 0;
List<Widget> _children;
List<File> _imageFileList = new List<File>();
@override
void initState() {
super.initState();
_children = [
AddPatientInfo(savePatient),
AddPatientImages(_imageFileList)
];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("New Patient Record"),
),
body: _children[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
items: [
BottomNavigationBarItem(icon: new Icon(Icons.create), title: new Text('Info')),
BottomNavigationBarItem(icon: new Icon(Icons.camera_alt), title: new Text('Images')),
],
onTap: (int index) {
setState(() {
_currentIndex = index;
});
},
),
);
}
}
AddPatientInfo
class AddPatientInfo extends StatefulWidget {
final Function savePatient;
AddPatientInfo(this.savePatient){
}
@override
State<StatefulWidget> createState() {
return _AddPatientInfoState();
}
}
class _AddPatientInfoState extends State<AddPatientInfo> with AutomaticKeepAliveClientMixin<AddPatientInfo> {
Function _savePatient;
String _firstName, _lastName, _gender, _phone, _email, _diabetesMeds, _hypertensionMeds, _others;
int _age, _diabetesYears, _hypertensionYears, _smokesPerDay, _smokerYears;
bool _diabetes = false, _hypertension = false, _smoker = false, _chestPain = false,
_cva = false, _ckd = false, _breathlessness = false,
_syncope = false, _sweating = false, _sweatingFeet = false;
List<String> _genderList = new List<String>();
List<String> _yesNoList = new List<String>();
List<File> _imageFileList = new List<File>();
@override
void initState() {
super.initState();
_savePatient = widget.savePatient;
_genderList.addAll(['Male', 'Female', 'Other']);
_yesNoList.addAll(['Yes', 'No']);
_gender = _genderList.elementAt(0);
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
body: Container(
margin: EdgeInsets.all(10.0),
child: Form(
child: new ListView(
children: <Widget>[
TextField(
decoration: InputDecoration(
labelText: 'Patient First Name',
labelStyle: TextStyle(
color: Colors.black
),
hintText: 'Enter patients first name'
),
onChanged: (String value) {
setState(() {
_firstName = value;
});
},
),
TextField(
decoration: InputDecoration(
labelText: 'Patient Last Name',
labelStyle: TextStyle(
color: Colors.black
),
hintText: 'Enter patients last name'
),
onChanged: (String value) {
setState(() {
_lastName = value;
});
},
),
//other textfield widgets below
],
),
)
),
);
}
@override
bool get wantKeepAlive => true;
}
What am I missing here? Is there a more elegant way to do maintain the data in the form?