【问题标题】:How to populating 2nd DropdownMenu based on first item selected flutter如何根据选择的第一项颤动填充第二个下拉菜单
【发布时间】:2020-08-19 07:41:32
【问题描述】:

我从 JSON 填充状态名称并显示为下拉列表,之后我根据选择的第一个值显示第二个下拉列表。但是我现在不知道如何在第一个下拉列表值更改时填充第二个下拉列表。我还想在选择第二个下拉值时获取位置 ID、名称和城市。

我的杰森

{
    "data": [
        {
            "state": "TEXAS",
            "locations": [
                {
                    "id": 1,
                    "name": "FITT Sugarland",
                    "city": "HOUSTON",
                    "state": "TEXAS",
                    "timezone": "",
                    "ownerName": "",
                    "ownerPhoneNumber": "",
                    "ownerEmail": "",
                    "ownerWebsite": "",
                    "capacity": 0,
                    "description": "HOUSTON SUGARLAND",
                    "createdBy": "",
                    "modifiedBy": "",
                    "createdAt": "2020-08-18T10:17:55.000Z",
                    "modifiedAt": "2020-08-18T10:17:55.000Z"
                },
                {
                    "id": 2,
                    "name": "FITT Pearland",
                    "city": "HOUSTON",
                    "state": "TEXAS",
                    "timezone": "",
                    "ownerName": "",
                    "ownerPhoneNumber": "",
                    "ownerEmail": "",
                    "ownerWebsite": "",
                    "capacity": 0,
                    "description": "second location",
                    "createdBy": "",
                    "modifiedBy": "",
                    "createdAt": "2020-08-18T10:18:38.000Z",
                    "modifiedAt": "2020-08-18T10:18:38.000Z"
                }
            ]
        }
    ]
}

模型类

class LocationModel {
  List<LocationList> data;

  LocationModel({this.data});

  LocationModel.fromJson(Map<String, dynamic> json) {
    if (json['data'] != null) {
      data = new List<LocationList>();
      json['data'].forEach((v) {
        data.add(new LocationList.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.data != null) {
      data['data'] = this.data.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class LocationList {
  String state;
  List<Locations> locations;

  LocationList({this.state, this.locations});

  LocationList.fromJson(Map<String, dynamic> json) {
    state = json['state'];
    if (json['locations'] != null) {
      locations = new List<Locations>();
      json['locations'].forEach((v) {
        locations.add(new Locations.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['state'] = this.state;
    if (this.locations != null) {
      data['locations'] = this.locations.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Locations {
  int id;
  String name;
  String city;
  String state;
  String timezone;
  String ownerName;
  String ownerPhoneNumber;
  String ownerEmail;
  String ownerWebsite;
  int capacity;
  String description;
  String createdBy;
  String modifiedBy;
  String createdAt;
  String modifiedAt;

  Locations(
      {this.id,
      this.name,
      this.city,
      this.state,
      this.timezone,
      this.ownerName,
      this.ownerPhoneNumber,
      this.ownerEmail,
      this.ownerWebsite,
      this.capacity,
      this.description,
      this.createdBy,
      this.modifiedBy,
      this.createdAt,
      this.modifiedAt});

  Locations.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    city = json['city'];
    state = json['state'];
    timezone = json['timezone'];
    ownerName = json['ownerName'];
    ownerPhoneNumber = json['ownerPhoneNumber'];
    ownerEmail = json['ownerEmail'];
    ownerWebsite = json['ownerWebsite'];
    capacity = json['capacity'];
    description = json['description'];
    createdBy = json['createdBy'];
    modifiedBy = json['modifiedBy'];
    createdAt = json['createdAt'];
    modifiedAt = json['modifiedAt'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['name'] = this.name;
    data['city'] = this.city;
    data['state'] = this.state;
    data['timezone'] = this.timezone;
    data['ownerName'] = this.ownerName;
    data['ownerPhoneNumber'] = this.ownerPhoneNumber;
    data['ownerEmail'] = this.ownerEmail;
    data['ownerWebsite'] = this.ownerWebsite;
    data['capacity'] = this.capacity;
    data['description'] = this.description;
    data['createdBy'] = this.createdBy;
    data['modifiedBy'] = this.modifiedBy;
    data['createdAt'] = this.createdAt;
    data['modifiedAt'] = this.modifiedAt;
    return data;
  }
}

我的代码

import 'dart:io';

import 'package:fittheorem/models/location_list.dart';
import 'package:fittheorem/providers/auth_session.dart';
import 'package:fittheorem/providers/user_details.dart';
import 'package:fittheorem/ui/widgets/error_snakbar.dart';
import 'package:fittheorem/utils/app_config.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';

class LocationUpdate extends StatefulWidget {
  @override
  _LocationUpdateState createState() => _LocationUpdateState();
}

class _LocationUpdateState extends State<LocationUpdate> {
  LocationModel _locationModel;
  bool isLoading = true;
  String _selectedState = "TEXAS";
  List<String> _statesList = [];

  String _selectedLocation = "FITT Sugarland";
  List<Locations> _locationsList = List();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    getList();
  }

  Future<void> getList() async {
    try {
      _locationModel = await Provider.of<UserDetails>(context, listen: false)
          .getLocationList("token");
      for (int i = 0; i < _locationModel.data.length; i++) {
        _statesList.add(_locationModel.data[i].state);
      }
      _locationsList = _locationModel.data[0].locations;
      _selectedState = _statesList[0];
      _selectedLocation = _locationsList[0].name;
      if (mounted) {
        setState(() {
          isLoading = false;
        });
      }
    } on HttpException catch (error) {
      CustomWidgets.buildErrorSnackbar(context);
    } catch (error) {
      CustomWidgets.buildErrorSnackbar(context);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: AppConfig.bgColor,
        child: SafeArea(
          child: Column(
            children: <Widget>[
              Container(
                padding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
                height: 40.0,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    GestureDetector(
                      behavior: HitTestBehavior.translucent,
                      onTap: () {
                        Navigator.pop(context, true);
                      },
                      child: Container(
                          height: 25.0,
                          width: 25.0,
                          child: SvgPicture.asset(AppConfig.backImage,
                              color: Colors.white, semanticsLabel: 'back')),
                    ),
                    Text('LOCATION',
                        style: GoogleFonts.roboto(
                          textStyle: TextStyle(
                              fontSize: 18.0, color: Color(0xffFFFFFF)),
                        )),
                    SizedBox(
                      width: 25.0,
                    ),
                  ],
                ),
              ),
              Expanded(
                child: Container(
                  color: Colors.white,
                  height: MediaQuery.of(context).size.height,
                  width: MediaQuery.of(context).size.width,
                  padding: EdgeInsets.all(30.0),
                  child: isLoading
                      ? Center(
                          child: AppConfig().myLoader(),
                        )
                      : Column(
                          mainAxisAlignment: MainAxisAlignment.start,
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            SizedBox(
                              height: 20.0,
                            ),
                            Padding(
                              padding: const EdgeInsets.only(left: 5.0),
                              child: Text('UPDATE YOUR LOCATION',
                                  style: GoogleFonts.roboto(
                                    textStyle: TextStyle(
                                        fontSize: 16.0,
                                        color: Color(0xff000000)),
                                  )),
                            ),
                            SizedBox(
                              height: 20.0,
                            ),
                            Container(
                              height: 40.0,
                              decoration: new BoxDecoration(
                                border: new Border.all(
                                    color: Colors.black54, width: 0.0),
                                borderRadius: new BorderRadius.circular(10.0),
                              ),
                              child: new DropdownButtonHideUnderline(
                                  child: ButtonTheme(
                                      alignedDropdown: true,
                                      child: new DropdownButton(
                                        value: _selectedState,
                                        hint: Text("State"),
                                        isExpanded: true,
                                        items: _statesList
                                            .map((String item) =>
                                                DropdownMenuItem<String>(
                                                    child: Text(item),
                                                    value: item))
                                            .toList(),
                                        onChanged: (String newValue) {
                                          if (mounted)
                                            setState(() {
                                              _selectedState = newValue;
                                            });
                                        },
                                        style: Theme.of(context)
                                            .textTheme
                                            .bodyText2,
                                      ))),
                            ),
                            SizedBox(
                              height: 20.0,
                            ),
                            Container(
                              height: 40.0,
                              decoration: new BoxDecoration(
                                border: new Border.all(
                                    color: Colors.black54, width: 0.0),
                                borderRadius: new BorderRadius.circular(10.0),
                              ),
                              child: new DropdownButtonHideUnderline(
                                  child: ButtonTheme(
                                      alignedDropdown: true,
                                      child: new DropdownButton(
                                        value: _selectedLocation,
                                        hint: Text("Location"),
                                        isExpanded: true,
                                        items: _locationsList.map((item) {
                                          return new DropdownMenuItem(
                                            child: new Text(item.name),
                                            value: item.name,
                                          );
                                        }).toList(),
                                        onChanged: (newValue) {
                                          if (mounted) print(newValue);
                                          setState(() {
                                            _selectedLocation = newValue;
                                          });
                                        },
                                        style: Theme.of(context)
                                            .textTheme
                                            .bodyText2,
                                      ))),
                            )
                          ],
                        ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: flutter dart drop-down-menu


    【解决方案1】:

    您可以在下面复制粘贴运行完整代码
    第一步:更改_selectedLocation的数据类型

    Locations _selectedLocation;
    

    第 2 步:_selectedState 的 onChanged

    onChanged: (String Value) {
          if (mounted)
            setState(() {
              _selectedState = Value;
    
              int index = _locationModel.data
                  .indexWhere((element) =>
                      element.state ==
                      _selectedState);
    
              _locationsList = _locationModel
                  .data[index].locations;
              _selectedLocation =
                  _locationsList[0];
            });
        },
    

    第 3 步:_selectedLocation 的 onChanged

    onChanged: (Value) {
          if (mounted) print(Value);
          setState(() {
            _selectedLocation = Value;
            print(
                "${_selectedLocation.name} ${_selectedLocation.id} ${_selectedLocation.city}");
          });
        },
    

    工作演示

    完整代码

    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    
    LocationModel locationModelFromJson(String str) =>
        LocationModel.fromJson(json.decode(str));
    
    class LocationModel {
      List<LocationList> data;
    
      LocationModel({this.data});
    
      LocationModel.fromJson(Map<String, dynamic> json) {
        if (json['data'] != null) {
          data = List<LocationList>();
          json['data'].forEach((v) {
            data.add(LocationList.fromJson(v));
          });
        }
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = Map<String, dynamic>();
        if (this.data != null) {
          data['data'] = this.data.map((v) => v.toJson()).toList();
        }
        return data;
      }
    }
    
    class LocationList {
      String state;
      List<Locations> locations;
    
      LocationList({this.state, this.locations});
    
      LocationList.fromJson(Map<String, dynamic> json) {
        state = json['state'];
        if (json['locations'] != null) {
          locations = List<Locations>();
          json['locations'].forEach((v) {
            locations.add(Locations.fromJson(v));
          });
        }
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = Map<String, dynamic>();
        data['state'] = this.state;
        if (this.locations != null) {
          data['locations'] = this.locations.map((v) => v.toJson()).toList();
        }
        return data;
      }
    }
    
    class Locations {
      int id;
      String name;
      String city;
      String state;
      String timezone;
      String ownerName;
      String ownerPhoneNumber;
      String ownerEmail;
      String ownerWebsite;
      int capacity;
      String description;
      String createdBy;
      String modifiedBy;
      String createdAt;
      String modifiedAt;
    
      Locations(
          {this.id,
          this.name,
          this.city,
          this.state,
          this.timezone,
          this.ownerName,
          this.ownerPhoneNumber,
          this.ownerEmail,
          this.ownerWebsite,
          this.capacity,
          this.description,
          this.createdBy,
          this.modifiedBy,
          this.createdAt,
          this.modifiedAt});
    
      Locations.fromJson(Map<String, dynamic> json) {
        id = json['id'];
        name = json['name'];
        city = json['city'];
        state = json['state'];
        timezone = json['timezone'];
        ownerName = json['ownerName'];
        ownerPhoneNumber = json['ownerPhoneNumber'];
        ownerEmail = json['ownerEmail'];
        ownerWebsite = json['ownerWebsite'];
        capacity = json['capacity'];
        description = json['description'];
        createdBy = json['createdBy'];
        modifiedBy = json['modifiedBy'];
        createdAt = json['createdAt'];
        modifiedAt = json['modifiedAt'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = Map<String, dynamic>();
        data['id'] = this.id;
        data['name'] = this.name;
        data['city'] = this.city;
        data['state'] = this.state;
        data['timezone'] = this.timezone;
        data['ownerName'] = this.ownerName;
        data['ownerPhoneNumber'] = this.ownerPhoneNumber;
        data['ownerEmail'] = this.ownerEmail;
        data['ownerWebsite'] = this.ownerWebsite;
        data['capacity'] = this.capacity;
        data['description'] = this.description;
        data['createdBy'] = this.createdBy;
        data['modifiedBy'] = this.modifiedBy;
        data['createdAt'] = this.createdAt;
        data['modifiedAt'] = this.modifiedAt;
        return data;
      }
    }
    
    class LocationUpdate extends StatefulWidget {
      @override
      _LocationUpdateState createState() => _LocationUpdateState();
    }
    
    class _LocationUpdateState extends State<LocationUpdate> {
      LocationModel _locationModel;
      bool isLoading = true;
      String _selectedState = "TEXAS";
      List<String> _statesList = [];
    
      Locations _selectedLocation;
      List<Locations> _locationsList = List();
    
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        getList();
      }
    
      Future<void> getList() async {
        try {
          /*_locationModel = await Provider.of<UserDetails>(context, listen: false)
              .getLocationList("token");*/
          String jsonString = '''
         {
        "data": [
            {
                "state": "TEXAS",
                "locations": [
                    {
                        "id": 1,
                        "name": "FITT Sugarland",
                        "city": "HOUSTON",
                        "state": "TEXAS",
                        "timezone": "",
                        "ownerName": "",
                        "ownerPhoneNumber": "",
                        "ownerEmail": "",
                        "ownerWebsite": "",
                        "capacity": 0,
                        "description": "HOUSTON SUGARLAND",
                        "createdBy": "",
                        "modifiedBy": "",
                        "createdAt": "2020-08-18T10:17:55.000Z",
                        "modifiedAt": "2020-08-18T10:17:55.000Z"
                    },
                    {
                        "id": 2,
                        "name": "FITT Pearland",
                        "city": "HOUSTON",
                        "state": "TEXAS",
                        "timezone": "",
                        "ownerName": "",
                        "ownerPhoneNumber": "",
                        "ownerEmail": "",
                        "ownerWebsite": "",
                        "capacity": 0,
                        "description": "second location",
                        "createdBy": "",
                        "modifiedBy": "",
                        "createdAt": "2020-08-18T10:18:38.000Z",
                        "modifiedAt": "2020-08-18T10:18:38.000Z"
                    }
                ]
            },
             {
                "state": "A",
                "locations": [
                    {
                        "id": 1,
                        "name": "A1",
                        "city": "A City 1",
                        "state": "A",
                        "timezone": "",
                        "ownerName": "",
                        "ownerPhoneNumber": "",
                        "ownerEmail": "",
                        "ownerWebsite": "",
                        "capacity": 0,
                        "description": "HOUSTON SUGARLAND",
                        "createdBy": "",
                        "modifiedBy": "",
                        "createdAt": "2020-08-18T10:17:55.000Z",
                        "modifiedAt": "2020-08-18T10:17:55.000Z"
                    },
                    {
                        "id": 2,
                        "name": "A2",
                        "city": "A city 2",
                        "state": "A",
                        "timezone": "",
                        "ownerName": "",
                        "ownerPhoneNumber": "",
                        "ownerEmail": "",
                        "ownerWebsite": "",
                        "capacity": 0,
                        "description": "second location",
                        "createdBy": "",
                        "modifiedBy": "",
                        "createdAt": "2020-08-18T10:18:38.000Z",
                        "modifiedAt": "2020-08-18T10:18:38.000Z"
                    }
                ]
            }
        ]
    }
          ''';
          _locationModel = locationModelFromJson(jsonString);
          for (int i = 0; i < _locationModel.data.length; i++) {
            _statesList.add(_locationModel.data[i].state);
          }
          _locationsList = _locationModel.data[0].locations;
          _selectedState = _statesList[0];
          _selectedLocation = _locationsList[0];
          if (mounted) {
            setState(() {
              isLoading = false;
            });
          }
          //} on HttpException catch (error) {
          // CustomWidgets.buildErrorSnackbar(context);
        } catch (error) {
          //CustomWidgets.buildErrorSnackbar(context);
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Container(
            //color: AppConfig.bgColor,
            child: SafeArea(
              child: Column(
                children: <Widget>[
                  Container(
                    padding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
                    height: 40.0,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                        GestureDetector(
                          behavior: HitTestBehavior.translucent,
                          onTap: () {
                            Navigator.pop(context, true);
                          },
                          child: Container(
                              height: 25.0,
                              width: 25.0,
                              child: Image.network(
                                  'https://picsum.photos/250?image=9',
                                  color: Colors.white)),
                        ),
                        Text('LOCATION',
                            style: TextStyle(
                              fontSize: 18.0,
                              color: Color(0xffFFFFFF),
                            )),
                        SizedBox(
                          width: 25.0,
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    child: Container(
                      color: Colors.white,
                      height: MediaQuery.of(context).size.height,
                      width: MediaQuery.of(context).size.width,
                      padding: EdgeInsets.all(30.0),
                      child: isLoading
                          ? Center(
                              child: CircularProgressIndicator(),
                            )
                          : Column(
                              mainAxisAlignment: MainAxisAlignment.start,
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                SizedBox(
                                  height: 20.0,
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(left: 5.0),
                                  child: Text('UPDATE YOUR LOCATION',
                                      style: TextStyle(
                                        fontSize: 16.0,
                                        color: Color(0xff000000),
                                      )),
                                ),
                                SizedBox(
                                  height: 20.0,
                                ),
                                Container(
                                  height: 40.0,
                                  decoration: BoxDecoration(
                                    border: Border.all(
                                        color: Colors.black54, width: 0.0),
                                    borderRadius: BorderRadius.circular(10.0),
                                  ),
                                  child: DropdownButtonHideUnderline(
                                      child: ButtonTheme(
                                          alignedDropdown: true,
                                          child: DropdownButton(
                                            value: _selectedState,
                                            hint: Text("State"),
                                            isExpanded: true,
                                            items: _statesList
                                                .map((String item) =>
                                                    DropdownMenuItem<String>(
                                                        child: Text(item),
                                                        value: item))
                                                .toList(),
                                            onChanged: (String Value) {
                                              if (mounted)
                                                setState(() {
                                                  _selectedState = Value;
    
                                                  int index = _locationModel.data
                                                      .indexWhere((element) =>
                                                          element.state ==
                                                          _selectedState);
    
                                                  _locationsList = _locationModel
                                                      .data[index].locations;
                                                  _selectedLocation =
                                                      _locationsList[0];
                                                });
                                            },
                                            style: Theme.of(context)
                                                .textTheme
                                                .bodyText2,
                                          ))),
                                ),
                                SizedBox(
                                  height: 20.0,
                                ),
                                Container(
                                  height: 40.0,
                                  decoration: BoxDecoration(
                                    border: Border.all(
                                        color: Colors.black54, width: 0.0),
                                    borderRadius: BorderRadius.circular(10.0),
                                  ),
                                  child: DropdownButtonHideUnderline(
                                      child: ButtonTheme(
                                          alignedDropdown: true,
                                          child: DropdownButton(
                                            value: _selectedLocation,
                                            hint: Text("Location"),
                                            isExpanded: true,
                                            items: _locationsList.map((item) {
                                              return DropdownMenuItem(
                                                child: Text(item.name),
                                                value: item,
                                              );
                                            }).toList(),
                                            onChanged: (Value) {
                                              if (mounted) print(Value);
                                              setState(() {
                                                _selectedLocation = Value;
                                                print(
                                                    "${_selectedLocation.name} ${_selectedLocation.id} ${_selectedLocation.city}");
                                              });
                                            },
                                            style: Theme.of(context)
                                                .textTheme
                                                .bodyText2,
                                          ))),
                                )
                              ],
                            ),
                    ),
                  )
                ],
              ),
            ),
          ),
        );
      }
    }
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: LocationUpdate(),
        );
      }
    }
    
    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>[
                Text(
                  'You have pushed the button this many times:',
                ),
                Text(
                  '$_counter',
                  style: Theme.of(context).textTheme.headline4,
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-30
      • 2021-12-11
      • 2012-01-04
      • 1970-01-01
      • 2017-09-19
      • 1970-01-01
      • 2016-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多