Flutter:如何根据所选的第一个下拉按钮值设置第二个下拉按钮(多级相关按钮)的值?
Flutter: How to set value of second dropdown button (multilevel dependent buttons) on the basis of first dropdown button value selected?
我正在尝试在 flutter 应用程序中实现多级依赖下拉按钮,并且按钮的值是从数据库中获取的。选择第二个下拉按钮值时出现错误。
`DistrictData _selectedDistrictValue;
BlockData _selectedBlockValue;
@override
void initState() {
// TODO: implement initState
_districtValues = databaseObject.getDistrictList(); //able to get
values from database
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Search'),
),
body: Container(
padding: const EdgeInsets.symmetric(vertical: 20.0),
child: Builder(
builder: (context) => Form(
key: _formKey,
autovalidate: true,
child: ListView(
// crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
SizedBox(height: 10.0),
Container(
padding: EdgeInsets.all(10.0),
child: getDistrictDropdown(),
),
Container(
padding: EdgeInsets.all(10.0),
child: getBlockDropdown(),
),
RaisedButton(
child: Text("Search"),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) =>
SearchResults()));
},
),
],
),
),
),
),
);
}
Widget getDistrictDropdown() {
return Center(
child: FutureBuilder(
future: _districtValues,
builder:
(BuildContext context, AsyncSnapshot<List<DistrictData>> snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
return DropdownButton<DistrictData>(
isExpanded: true,
hint: Text("District"),
items: snapshot.data
.map((value) => DropdownMenuItem<DistrictData>(
child: Text(value.districtName),
value: value,
))
.toList(),
onChanged: (selectedValue) {
setState(() {
_selectedDistrictValue = selectedValue;
});
},
value: _selectedDistrictValue,
);
},
),
);
}
Widget getBlockDropdown() {
if (_selectedDistrictValue != null) {
return FutureBuilder(
future: databaseObject.getBlockList(_selectedDistrictValue.districtCode), //able to get blocks from database
builder:
(BuildContext context, AsyncSnapshot<List<BlockData>> snapshot) {
if (!snapshot.hasData){return Container(
child: Text("Please Select District first"),
);}
else{
return DropdownButton<BlockData>(
isExpanded: true,
hint: Text("Block"),
items: snapshot.data
.map((value) => DropdownMenuItem<BlockData>(
child: Text(value.blockName),
value: value,
))
.toList(),
onChanged: (selectedValue) {
setState(() {
_selectedBlockValue = selectedValue;
});
},
value: _selectedBlockValue, //getting error while setting value here. If i commented this it works fine but then i not able to show selected value on dropdown
);
}
},
);
}`
选择第二个下拉值时出现错误:
The following assertion was thrown building
FutureBuilder>(dirty, state: I/flutter (26965):
_FutureBuilderState>#7dd80): I/flutter (26965): 'package:flutter/src/material/dropdown.dart': Failed assertion: line
608 pos 15: 'items == null || I/flutter (26965): items.isEmpty ||
value == null || items.where((DropdownMenuItem item) => item.value
== I/flutter (26965): value).length == 1': is not true.
是这个吗?
if (_selectedDistrictValue != null)
应该是 if (_selectedDistrictValue == null)
由于 _selectedDistrictValue
来自您的第一个下拉列表 getDistrictDropdown
,并且您在选择 (onChanged
) 之前不会获得它的值,因此它将 null
开始。
但是你的第二个下拉列表 getBlockDropdown
已经为 != null
设定了 child: Text("Please Select District first")
,所以这意味着对于 == null
,它已经在尝试 items: snapshot.data.map((value) =>
您甚至已经选择了第一个下拉列表。
你应该在更改后删除 _selectedBlockValue
_selectedDistrictValue
因为这个值不在另一个列表中
在第一个下拉列表的 onChange 中
onChanged: (selectedValue) {
setState(() {
_selectedDistrictValue = selectedValue;
_selectedBlokValue != null ? _selectedBlokValue = null : null;
});
},
我正在尝试在 flutter 应用程序中实现多级依赖下拉按钮,并且按钮的值是从数据库中获取的。选择第二个下拉按钮值时出现错误。
`DistrictData _selectedDistrictValue;
BlockData _selectedBlockValue;
@override
void initState() {
// TODO: implement initState
_districtValues = databaseObject.getDistrictList(); //able to get
values from database
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Search'),
),
body: Container(
padding: const EdgeInsets.symmetric(vertical: 20.0),
child: Builder(
builder: (context) => Form(
key: _formKey,
autovalidate: true,
child: ListView(
// crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
SizedBox(height: 10.0),
Container(
padding: EdgeInsets.all(10.0),
child: getDistrictDropdown(),
),
Container(
padding: EdgeInsets.all(10.0),
child: getBlockDropdown(),
),
RaisedButton(
child: Text("Search"),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) =>
SearchResults()));
},
),
],
),
),
),
),
);
}
Widget getDistrictDropdown() {
return Center(
child: FutureBuilder(
future: _districtValues,
builder:
(BuildContext context, AsyncSnapshot<List<DistrictData>> snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
return DropdownButton<DistrictData>(
isExpanded: true,
hint: Text("District"),
items: snapshot.data
.map((value) => DropdownMenuItem<DistrictData>(
child: Text(value.districtName),
value: value,
))
.toList(),
onChanged: (selectedValue) {
setState(() {
_selectedDistrictValue = selectedValue;
});
},
value: _selectedDistrictValue,
);
},
),
);
}
Widget getBlockDropdown() {
if (_selectedDistrictValue != null) {
return FutureBuilder(
future: databaseObject.getBlockList(_selectedDistrictValue.districtCode), //able to get blocks from database
builder:
(BuildContext context, AsyncSnapshot<List<BlockData>> snapshot) {
if (!snapshot.hasData){return Container(
child: Text("Please Select District first"),
);}
else{
return DropdownButton<BlockData>(
isExpanded: true,
hint: Text("Block"),
items: snapshot.data
.map((value) => DropdownMenuItem<BlockData>(
child: Text(value.blockName),
value: value,
))
.toList(),
onChanged: (selectedValue) {
setState(() {
_selectedBlockValue = selectedValue;
});
},
value: _selectedBlockValue, //getting error while setting value here. If i commented this it works fine but then i not able to show selected value on dropdown
);
}
},
);
}`
选择第二个下拉值时出现错误:
The following assertion was thrown building FutureBuilder>(dirty, state: I/flutter (26965): _FutureBuilderState>#7dd80): I/flutter (26965): 'package:flutter/src/material/dropdown.dart': Failed assertion: line 608 pos 15: 'items == null || I/flutter (26965): items.isEmpty || value == null || items.where((DropdownMenuItem item) => item.value == I/flutter (26965): value).length == 1': is not true.
是这个吗?
if (_selectedDistrictValue != null)
应该是 if (_selectedDistrictValue == null)
由于 _selectedDistrictValue
来自您的第一个下拉列表 getDistrictDropdown
,并且您在选择 (onChanged
) 之前不会获得它的值,因此它将 null
开始。
但是你的第二个下拉列表 getBlockDropdown
已经为 != null
设定了 child: Text("Please Select District first")
,所以这意味着对于 == null
,它已经在尝试 items: snapshot.data.map((value) =>
您甚至已经选择了第一个下拉列表。
你应该在更改后删除 _selectedBlockValue
_selectedDistrictValue
因为这个值不在另一个列表中
在第一个下拉列表的 onChange 中
onChanged: (selectedValue) {
setState(() {
_selectedDistrictValue = selectedValue;
_selectedBlokValue != null ? _selectedBlokValue = null : null;
});
},