我根据TextFormField输入在步进器中动态显示Flutter下拉菜单,但是当我尝试选择其中一项时,所选值(_valueDropdownGrade)发生了变化,但始终将默认值保留在UI中,尽管其中包含更新将变量转换为setState()方法。
class _SchoolProfileState extends State<SchoolProfile> {
int currStep = 0;
static final FocusNode _nameFocus = FocusNode();
static final FocusNode _phoneFocus = FocusNode();
static final FocusNode _emailFocus = FocusNode();
static final FocusNode _addressFocus = FocusNode();
static final FocusNode _numberChildFocus = FocusNode();
static final List<FocusNode> _listChildFocus = [];
static final FocusNode _ageFocus = FocusNode();
static SchoolProfileData data = new SchoolProfileData();
GlobalKey<FormState> _formKey = GlobalKey<FormState>();
TextEditingController _controllerNumberKids = TextEditingController();
TextEditingController _controllerAddressSearch = TextEditingController();
Timer _throttle;
String _valueDropdownGrade = 'MATERNELLE';
static var childrenFields = new List<Widget>();
_fieldFocusChange(BuildContext context, FocusNode currentFocus,FocusNode nextFocus) {
currentFocus.unfocus();
FocusScope.of(context).requestFocus(nextFocus);
}
@override
void initState() {
_controllerNumberKids.addListener(onNumberChildChanged);
_controllerAddressSearch.addListener(onAddressSearchChanged);
SchedulerBinding.instance.addPostFrameCallback((Duration _) {
FocusScope.of(context).requestFocus(_nameFocus);
});
super.initState();
}
void onNumberChildChanged() {
childrenFields.clear();
data.childrenNames.clear();
for (var i = 0; i < int.parse(_controllerNumberKids.text); i++) {
childrenFields.add(
new TextFormField(
textInputAction: TextInputAction.next,
focusNode: _listChildFocus[i],
onFieldSubmitted: (term) {
if (i == _listChildFocus.length - 1) {
formKeys[currStep].currentState.save();
if (currStep < getSteps(context).length - 1) {
currStep = currStep + 1;
}
_fieldFocusChange(context, _listChildFocus[i], _ageFocus);
}
else
_fieldFocusChange(
context, _listChildFocus[i], _listChildFocus[i + 1]);
},
onSaved: (String value) {
data.childrenNames.add(value);
},
keyboardType: TextInputType.text,
autocorrect: false,
decoration: InputDecoration(
labelText: 'Enter your child name',
hintText: 'Enter a child name',
//filled: true,
icon: const Icon(Icons.person),
border: InputBorder.none,
labelStyle: TextStyle(
decorationStyle: TextDecorationStyle.solid)),
)
);
childrenFields.add(
new DropdownButtonHideUnderline(
child:
Container(
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
side: BorderSide(width: 1.0, style: BorderStyle.solid),
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
),
child:
DropdownButton<String>(
icon: Icon(Icons.school),
hint: Text('Choose the class'),
onChanged: (newValue) {
setState(() => _valueDropdownGrade = newValue);
},
value: _valueDropdownGrade,
items:
<String>[_valueDropdownGrade,'GRADE 1', 'GRADE 2', 'GRADE 3', 'GRADE 4', 'GRADE 5', 'GRADE 6', 'GRADE 7', 'GRADE 8', 'GRADE 9', 'GRADE 10', 'GRADE 11', 'GRADE 12']
.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: SizedBox(
width: 100.0, // for example
child: Text(value, textAlign: TextAlign.center),
));
}).toList()))));
}
}
Step(
title: const Text('Number of children'),
// subtitle: const Text('Subtitle'),
isActive: true,
state: StepState.indexed,
content: Form(
key: formKeys[4],
child: Column(
children: <Widget>[
TextFormField(
textInputAction: TextInputAction.next,
focusNode: _numberChildFocus,
onFieldSubmitted: (term) {
formKeys[currStep].currentState.save();
if (currStep < getSteps(context).length - 1) {
currStep = currStep + 1;
}
for (var i = 0; i < int.parse(_controllerNumberKids.text); ++i) {
_listChildFocus.add(FocusNode());
}
_fieldFocusChange(context, _numberChildFocus, _listChildFocus[0]);
},
autocorrect: false,
keyboardType: TextInputType.numberWithOptions(
decimal: false,
signed: true,
),
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter.digitsOnly
],
controller: _controllerNumberKids,
decoration: InputDecoration(
labelText: 'Enter number of children',
hintText: 'Enter children number',
icon: const Icon(Icons.child_care),
labelStyle:
TextStyle(decorationStyle: TextDecorationStyle.solid)),
),
],
),
)),
Step(
title: const Text('List of Children'),
// subtitle: const Text('Subtitle'),
isActive: true,
state: StepState.indexed,
content: Form(
key: formKeys[5],
child:
Column(
children: <Widget>[
ListView.builder(
shrinkWrap: true,
itemCount: childrenFields.length,
itemBuilder: (context, index) {
return childrenFields[index];
}
)]
),
)),
答案 0 :(得分:0)
您可以在下面复制粘贴运行完整代码
您需要使用StatefulBuilder
代码段
childrenFields.add(
StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
return DropdownButtonHideUnderline(
child: Container(
工作演示
完整代码
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SchoolProfile(),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class SchoolProfile extends StatefulWidget {
@override
_SchoolProfileState createState() => _SchoolProfileState();
}
class _SchoolProfileState extends State<SchoolProfile> {
static var childrenFields = new List<Widget>();
String _valueDropdownGrade;
List<String> items = [
'GRADE 1',
'GRADE 2',
'GRADE 3',
'GRADE 4',
'GRADE 5',
'GRADE 6',
'GRADE 7',
'GRADE 8',
'GRADE 9',
'GRADE 10',
'GRADE 11',
'GRADE 12'
];
@override
void initState() {
_valueDropdownGrade = items[0];
childrenFields.add(
StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
return DropdownButtonHideUnderline(
child: Container(
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
side: BorderSide(width: 1.0, style: BorderStyle.solid),
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
),
child: DropdownButton<String>(
icon: Icon(Icons.school),
hint: Text('Choose the class'),
onChanged: (newValue) {
setState(() => _valueDropdownGrade = newValue);
},
value: _valueDropdownGrade,
items: items.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: SizedBox(
width: 100.0, // for example
child: Text(value, textAlign: TextAlign.center),
));
}).toList())));
}));
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
child: Stepper(steps: [
Step(
title: Text("Start"),
content: Form(
child: Column(children: <Widget>[
ListView.builder(
shrinkWrap: true,
itemCount: childrenFields.length,
itemBuilder: (context, index) {
return childrenFields[index];
})
]),
),
)
]));
}
}
答案 1 :(得分:0)
在dropDownList内删除 _valueDropdownGrade 并将“ MATERNELLE ”直接放在dropDown列表内。
String _valueDropdownGrade = 'MATERNELLE';
DropdownButton<String>(
icon: Icon(Icons.school),
hint: Text('Choose the class'),
onChanged: (newValue) {
setState(() => _valueDropdownGrade = newValue);
},
value: _valueDropdownGrade,
items:
<String>['MATERNELLE','GRADE 1', 'GRADE 2', 'GRADE 3', 'GRADE 4', 'GRADE 5', 'GRADE 6', 'GRADE 7', 'GRADE 8', 'GRADE 9', 'GRADE 10', 'GRADE 11', 'GRADE 12']
.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: SizedBox(
width: 100.0, // for example
child: Text(value, textAlign: TextAlign.center),
));
}).toList()))));