我有一个名为AddPatientView的页面,其中的BottomNavigationBar包含AddPatientInfo和AddPatientImages页面。所有这三个都是有状态的小部件。
默认情况下,AddPatientInfo将打开,其中包含一堆TextField(用于输入患者信息),用户可以在AddPatientImages页面中添加图像。
问题是,如果我在AddPatientInfo上填充TextField,然后转到AddPatientImages,然后返回,则所有TextField都是空的。正确的做法是,由于整个小部件树都得到了重建,因此我丢失了所有填充的数据。
因此,我正在实现AutomaticKeepAliveClientMixin
,以便即使更改选项卡也可以保持状态。但这似乎不起作用:
Working Gif via GIPHY
这是我的代码:
AddPatientView (父级)
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;
}
我在这里想念什么?有没有更优雅的方式来维护表单中的数据?
最佳答案
如果希望AutomaticKeepAliveClientMixin继续工作,请使用PageView包裹正文,代码应如下所示
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>();
// add
final pageController = PageController();
void onPageChanged(int index) {
setState(() {
_currentIndex = index;
});
}
@override
void initState() {
super.initState();
_children = [AddPatientInfo(savePatient), AddPatientImages(_imageFileList)];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("New Patient Record"),
),
// here!!!
body: PageView(
children: _children,
controller: pageController,
onPageChanged: onPageChanged,
),
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;
// });
// update
pageController.jumpToPage(index);
},
),
);
}
}
但是如果您只是想保持页面状态,建议您使用IndexedStack,它非常简单,不需要AutomaticKeepAliveClientMixin,代码应该像这样
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: IndexedStack(
index:_currentIndex,
children:_children
),
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;
});
},
),
);
}
}
关于dart - Flutter:AutomaticKeepAliveClientMixin无法与BottomNavigationBar一起使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53011686/