Flutter:如何根据选择的第一个下拉按钮值设置第二个下拉按钮(多级相关按钮)的值?

Posted

技术标签:

【中文标题】Flutter:如何根据选择的第一个下拉按钮值设置第二个下拉按钮(多级相关按钮)的值?【英文标题】:Flutter: How to set value of second dropdown button (multilevel dependent buttons) on the basis of first dropdown button value selected? 【发布时间】:2019-12-01 10:53:35 【问题描述】:

我正在尝试在颤振应用程序中实现多级相关下拉按钮,并且按钮的值是从数据库中获取的。选择第二个下拉按钮值时出现错误。

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

选择第二个下拉值时出现错误:

以下断言被抛出构建 FutureBuilder>(脏,状态:I/flutter(26965): _FutureBuilderState>#7dd80): I/flutter (26965): 'package:flutter/src/material/dropdown.dart': 断言失败:行 608 位置 15: '项目 == 空 ||我/颤振(26965):items.isEmpty || 值 == 空 || items.where((DropdownMenuItem item) => item.value == I/flutter (26965): value).length == 1': 不正确。

【问题讨论】:

【参考方案1】:

是这个吗?

if (_selectedDistrictValue != null) 应该是if (_selectedDistrictValue == null)

由于_selectedDistrictValue 来自您的第一个下拉列表getDistrictDropdown,并且直到选择(onChanged)后您才能获得它的值,所以在开始时它将是null

但是您的第二个下拉列表getBlockDropdown 已将child: Text("Please Select District first") 限定为!= null,这意味着对于== null,它已经在尝试执行items: snapshot.data.map((value) =&gt;,甚至在您选择第一个下拉列表之前。

【讨论】:

【参考方案2】:

你应该在更改_selectedDistrictValue 后删除_selectedBlockValue,因为这个值不在另一个列表中

在 onChnage 中用于第一个下拉菜单

onChanged: (selectedValue) 
      setState(() 
        _selectedDistrictValue = selectedValue;
        _selectedBlokValue != null ? _selectedBlokValue = null : null;
      );
    ,

【讨论】:

以上是关于Flutter:如何根据选择的第一个下拉按钮值设置第二个下拉按钮(多级相关按钮)的值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在EXCEL中设置下拉箭头筛选内容?

如何根据使用 jQuery/AJAX 和 PHP/MySQL 选择的第一个下拉列表填充第二个下拉列表?

如何根据其他下拉选择将本地 Json 加载到 Flutter DropDown?

如何根据 Flutter 中的条件导航到页面

如何设置动态下拉列表的选定值

JQuery - 如何根据值选择下拉项