如何根据第一个DropdownButton的选择加载第二个DropdownButton

时间:2019-01-02 02:34:30

标签: flutter

我刚刚开始学习颤动。

我有两个DropdownButtons,我试图根据区域json中cid对第一个过滤的选择来填充第二个。

{"countries":[{"cid":"2","name":"Country A"},{"cid":"3","name":"Country B"}]}

{"regions":[{"rid":"1","cid":"2","name":"Region 1 of Country A"},{"rid":"2","cid":"2","name":"Region 2 of Country A"},{"rid":"3","cid":"3","name":"Region 1 of Country B"},{"rid":"4","cid":"3","name":"Region 2 of Country B"}]}

void main () {

  runApp(new SearchAssembly());
}
class SearchAssembly extends StatefulWidget{
 SearchAssembly({Key key}):super(key:key);

 @override
 _SearchAssemblyState createState() => new _SearchAssemblyState ();

}
class _SearchAssemblyState extends State<SearchAssembly> {

 List _countryData = new List();
 List _regionData = new List();


 List<DropdownMenuItem<String>> _dropDownMenuItemsCountries;
 List<DropdownMenuItem<String>> _dropDownMenuItemsRegions;

 String _selectedCountry;
 String _selectedRegion;


 Future<List> getCountry() async{

http.Response response = await http.get(countryUrl);

var results= await json.decode(response.body)['countries'];
return results;
}

Future<List> getRegions() async{

http.Response response = await http.get(regionsUrl);

var results= await json.decode(response.body)['regions'];
return results;
}
void loadData () async{

   _countryData = await getCountry();
    _regionData = await getRegions();

    setState(() {
      _selectedCountry="2";
      _selectedRegion="1";
      _dropDownMenuItemsCountries = getDropDownMenuItemCountries();

_dropDownMenuItemsRegions=getDropDownMenuItemRegions(_selectedCountry);
});
}

@override
 void initState() {
  loadData ();
  super.initState();
}

List<DropdownMenuItem<String>> getDropDownMenuItemCountries( ) {

    List<DropdownMenuItem<String>> items = new List();

     if (_countryData.isNotEmpty) {

        for (int i = 0; i < _countryData.length; i++) {

        String cid= _countryData[i]['cid'].toString();
        String name=_countryData[i]['name'].toString();

        items.add(new DropdownMenuItem(value: cid,
         child: new Text(name)

       ));
      }
    }

    return items;
 }



  void changeDropDownItemCountry(String selectedCountry){

      setState(() {
      _selectedCountry=selectedCountry;

       _dropDownMenuItemsRegions = 
  getDropDownMenuItemRegions(_selectedCountry);


 });
}


 List<DropdownMenuItem<String>> getDropDownMenuItemRegions(String filterBy) 
{

List<DropdownMenuItem<String>> items = new List();


if(_regionData.isNotEmpty) {

  for (int i = 0; i < _regionData.length; i++) {

    if (_regionData[i]['cid'].toString() == filterBy) {
      String rid = _regionData[i]['rid'].toString();
      String name = _regionData[i]['name'].toString();

      items.add(new DropdownMenuItem(value: rid,
          child: new Text(name)

      ));
    }
  }


  }


 return items;
 }

void changeDropDownItemRegion(String selectedRegion){

    setState(() {
     _selectedRegion=selectedRegion;

     print ("The selected Region is: $_selectedRegion");
   });
 }


@override
Widget build(BuildContext context) {


// TODO: implement build
 return new MaterialApp(
   home: Scaffold(
    appBar: AppBar(
      title: Text(" Locator"),
      elevation: 0.1,
      backgroundColor: new Color(0xFF546E7A),
    ),

    backgroundColor: Colors.blueGrey.shade500,
    body:  ListView(
         padding: const EdgeInsets.all(10.0),
      children: <Widget>[



       new DropdownButtonHideUnderline(child:
       new DropdownButton(
         value: _selectedCountry,
         items: _dropDownMenuItemsCountries,
         onChanged: changeDropDownItemCountry,
         isExpanded: true,
         isDense: true,

       ),

       ),

       new SizedBox(
         child: null,height: 10.0,
       ),

       new DropdownButtonHideUnderline(child:
       new DropdownButton(
         value: _selectedRegion,
         items: _dropDownMenuItemsRegions,
         onChanged: changeDropDownItemRegion,
         isExpanded: true,
         isDense: true,

       ),

       )


      ],


     )
   ));

 }


}

错误:

I/flutter ( 6426): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 6426): The following assertion was thrown building SearchAssembly(dirty, state:
I/flutter ( 6426): _SearchAssemblyState#4c4ac):
I/flutter ( 6426): 'package:flutter/src/material/dropdown.dart': Failed assertion: line 514 pos 15: 'items == null ||
I/flutter ( 6426): value == null || items.where((DropdownMenuItem<T> item) => item.value == value).length == 1': is not
I/flutter ( 6426): true.
I/flutter ( 6426): 
I/flutter ( 6426): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter ( 6426): more information in this error message to help you determine and fix the underlying cause.
I/flutter ( 6426): In either case, please report this assertion by filing a bug on GitHub:
I/flutter ( 6426):   https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter ( 6426): 
I/flutter ( 6426): When the exception was thrown, this was the stack:
I/flutter ( 6426): #2      new DropdownButton (package:flutter/src/material/dropdown.dart:514:15)
I/flutter ( 6426): #3      _SearchAssemblyState.build (package:flutter_dashboard/search_assembly_widget.dart:212:16)
I/flutter ( 6426): #4      StatefulElement.build (package:flutter/src/widgets/framework.dart:3809:27)
I/flutter ( 6426): #5      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3721:15)
I/flutter ( 6426): #6      Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter ( 6426): #7      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2286:33)
I/flutter ( 6426): #8      _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:676:20)
I/flutter ( 6426): #9      _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:219:5)
I/flutter ( 6426): #10     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
I/flutter ( 6426): #11     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
I/flutter ( 6426): #12     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5)
I/flutter ( 6426): #13     _invoke (dart:ui/hooks.dart:154:13)
I/flutter ( 6426): #14     _drawFrame (dart:ui/hooks.dart:143:3)
I/flutter ( 6426): (elided 2 frames from class _AssertionError)
I/flutter ( 6426): ════════════════════════════════════════════════════════════════════════════════════════════════════

1 个答案:

答案 0 :(得分:0)

发生问题是因为_selectedRegion没有更新。

List<DropdownMenuItem<String>> getDropDownMenuItemRegions(String filterBy) {
    List<DropdownMenuItem<String>> items = new List();
    if (_regionData.isNotEmpty) {
      for (int i = 0; i < _regionData.length; i++) {
        if (_regionData[i]['cid'] == filterBy) {
          print(_regionData[i]['cid']);
          String rid = _regionData[i]['rid'];
          String name = _regionData[i]['name'];
          setState(() {
            _selectedRegion = _regionData[i]['rid'];
          });
          items.add(new DropdownMenuItem(value: rid, child: new Text(name)));
        }
      }
    }

    return items;
  }

DropdownMenuItem中的最后一项

相关问题