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;
      });
    },