首页 > 解决方案 > 如何显示选择的值?

问题描述

我从 DropdownMenuItem 中选择的值(例如:Malaysia (+06) ),选择的值将被显示,但是当我导航回或继续到其他界面时,它会消失。

问题:如何使选择的值保持在下拉按钮框中?

有什么办法可以解决问题吗?

下面是我在 showModalBottomSheet 中的代码段:

String _selectedCountryCode;
List jsonResult = List();
 loadJsonData() async {
    String data = await rootBundle.loadString('assets/country_code.json');
    jsonResult = json.decode(data);
    print(jsonResult);
  }
 @override
  void initState() {
    super.initState();
    loadJsonData();
    phoneController = TextEditingController();
  }

小部件部件

Row(
                                        mainAxisAlignment: MainAxisAlignment.end,
                                        crossAxisAlignment: CrossAxisAlignment.end,
                                        children: <Widget>[
                                          TextButton(
                                            onPressed: () {
                                              _showModalPhoneWidget();
                                            },
                                            child: Text(
                                              "Request OTP", style: TextStyle(
                                              color: const Color(0xff002aff),
                                              fontSize: 15,
                                            ),
                                            ),)
                                        ],
                                      )

_showModalPhoneWidget 方法部分

_showModalPhoneWidget() {
    showModalBottomSheet(
        backgroundColor: Colors.green,
        context: context,
        isDismissible: true,
        //transitionAnimationController: Duration(milliseconds: 400),
        builder: (context) {
          return StatefulBuilder(
            builder: (context, setStateSTB) => ClipRRect(
              borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(10.0),
                  topRight: Radius.circular(10.0)),
              child: Container(
                height: 250,
                color: Colors.white,
                child: Column(
                  children: <Widget>[
                    Padding(
                      padding: EdgeInsets.only(top: 10.0),
                      child: Text(
                        "Update Phone",
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          color: Colors.black,
                          fontSize: 18.0,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                    Padding(
                      padding: EdgeInsets.only(top: 20.0, left: 10.0),
                      child: Row(
                        children: <Widget>[
                          Text(
                            "Tel No",
                            style:
                            TextStyle(color: Colors.black, fontSize: 15.0),
                          ),
                          Text(
                            "*",
                            style: TextStyle(color: Colors.red, fontSize: 15.0),
                          ),
                        ],
                      ),
                    ),

                    Container(
                      margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
                      height: 50.0,
                      width: double.infinity,
                      decoration: BoxDecoration(
                          border: Border.all(color: const Color(0xffededed))),
                      child: Stack(
                        children: <Widget>[
                          Row(
                            children: <Widget>[
                              Container(
                                margin: EdgeInsets.only(top: 5.0, left: 5.0),
                                height: 40.0,
                                width: 100.0,
                                child: DropdownButtonHideUnderline(
                                  child: ButtonTheme(
                                    alignedDropdown: false,
                                    child: DropdownButton(
                                    // child: DropdownButton<Map<String, String>>(
                                      isExpanded: true,
                                      value: _selectedCountryCode,
                                      selectedItemBuilder: (BuildContext context)
                                      {
                                        return jsonResult.map<Widget>((element) {
                                          return Text("${element['dial_code']}", textAlign: TextAlign.center);
                                        }).toList();
                                      },
                                      items: jsonResult.map((element) {
                                        return DropdownMenuItem(
                                          child: Text("${element['name']} (${element['dial_code']})", overflow: TextOverflow.clip, maxLines: 1,),
                                          value: element['dial_code'],
                                        );
                                      }).toList(),
                                      onChanged: (val) async {
                                        SharedPreferences prefs = await SharedPreferences.getInstance();
                                        //* to change on dialog
                                        setStateSTB(() {
                                           _selectedCountryCode = val;
                                          prefs.setString('_selectedCountryCode', _selectedCountryCode);
                                          print('select code: $_selectedCountryCode' );
                                        });
                                        //* to change on StateLevel
                                        setState(() {
                                          _selectedCountryCode = val;
                                          prefs.setString('_selectedCountryCode', _selectedCountryCode);
                                        });
                                      },
                                    ),
                                  ),
                                ),
                              ),
                              // if(_isEditingText)
                                Container(
                                  width: 120,
                                  height: 40,
                                  child: TextField(
                                    controller: phoneController,
                                    keyboardType: TextInputType.number,
                                    inputFormatters: <TextInputFormatter>[
                                      FilteringTextInputFormatter.digitsOnly
                                    ], // Only numbers can be entered
                                    textAlign: TextAlign.center,
                                    decoration: InputDecoration(
                                      border: InputBorder.none,
                                      hintText: 'Tel No. Ex:0133333333',
                                    ),
                                  onSubmitted: (newPhoneNo) {
                                      setState(() {
                                        initialText = newPhoneNo;
                                        _isEditingText = false;
                                      });
                                  },
                                ),
                              ),
                              Container(
                                height: 40,
                                width: 100,
                                child: InkWell(
                                  onTap: () {
                                    setState(() {
                                      _isEditingText = true;
                                    });
                                  },
                                ),
                              ),

                            ],
                          )
                        ],
                      ),

                    ),
                    Container(
                      margin: EdgeInsets.all(20.0),
                      child: ButtonTheme(
                        minWidth: double.infinity,
                        height: 50,
                        child: OutlineButton(
                          child: Text("Continue",
                              style: TextStyle(color: Colors.amber, fontSize: 16)),
                          borderSide: BorderSide(
                            color: Colors.amber,
                          ),
                          highlightElevation: 10.0,
                          onPressed: () {
                           
                          },
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          );
        });
  }

这是我的本地 JSON 数据:

[
  {
    "name": "Malaysia",
    "dial_code": "+60",
    "code": "MY"
  },
  {
    "name": "Afghanistan",
    "dial_code": "+93",
    "code": "AF"
  },
  {
    "name": "Aland Islands",
    "dial_code": "+358",
    "code": "AX"
  },
  {
    "name": "Albania",
    "dial_code": "+355",
    "code": "AL"
  },
  {
    "name": "Algeria",
    "dial_code": "+213",
    "code": "DZ"
  },
  {
    "name": "AmericanSamoa",
    "dial_code": "+1684",
    "code": "AS"
  },
  {
    "name": "Andorra",
    "dial_code": "+376",
    "code": "AD"
  },
  {
    "name": "Angola",
    "dial_code": "+244",
    "code": "AO"
  },
  {
    "name": "Anguilla",
    "dial_code": "+1264",
    "code": "AI"
  },
  {
    "name": "Antarctica",
    "dial_code": "+672",
    "code": "AQ"
  },
  {
    "name": "Antigua and Barbuda",
    "dial_code": "+1268",
    "code": "AG"
  },
  {
    "name": "Argentina",
    "dial_code": "+54",
    "code": "AR"
  },
  {
    "name": "Armenia",
    "dial_code": "+374",
    "code": "AM"
  },
  {
    "name": "Aruba",
    "dial_code": "+297",
    "code": "AW"
  },
  {
    "name": "Australia",
    "dial_code": "+61",
    "code": "AU"
  },
  {
    "name": "Austria",
    "dial_code": "+43",
    "code": "AT"
  },
  {
    "name": "Azerbaijan",
    "dial_code": "+994",
    "code": "AZ"
  },
  {
    "name": "Bahamas",
    "dial_code": "+1242",
    "code": "BS"
  },
  {
    "name": "Bahrain",
    "dial_code": "+973",
    "code": "BH"
  },
  {
    "name": "Bangladesh",
    "dial_code": "+880",
    "code": "BD"
  },
  {
    "name": "Barbados",
    "dial_code": "+1246",
    "code": "BB"
  },
  {
    "name": "Belarus",
    "dial_code": "+375",
    "code": "BY"
  },
  {
    "name": "Belgium",
    "dial_code": "+32",
    "code": "BE"
  },
]

标签: flutterdrop-down-menuflutter-showmodalbottomsheet

解决方案


对于问题 1,您可以使用Mapfor DropdownMenuItem。虽然只显示namedial_code你可以设置孩子喜欢

items: jsonResult.map((element) {
return DropdownMenuItem(
  child: Text(
      "${element['name']} ${element['dial_code']}"),
  value: element,
);
}).toList(),

对于问题 2更新对话框上的状态需要使用StatefulBuilder并使用它 setstate来更新对话框,最好重命名它。

         return StatefulBuilder(
            builder: (context, setStateSTB) => ClipRRect(
               ......
                    onChanged: (_selectedCountryCode) {
                                  //* to change on dialog
                                  setStateSTB(() {
                                    _defaultCountryCode = _selectedCountryCode;
                                  });

                                  //* to change on StateLevel
                                  setState(() {
                                    _defaultCountryCode = _selectedCountryCode;
                                  });
                                },


更新问题所在loadJsonData()

 Future<void> loadJsonData() async {
    /// 
    String data = await rootBundle.loadString('assets/country_code.json');
    final jsonString = jsonDecode(data) as List;

    final item = jsonString.map((e) {
      return {
        'name': e['name'] as String,
        'dial_code': e['dial_code'] as String,
        'code': e['code'] as String,
      };
    }).toList();

    setState(() {
      jsonResult = item;
    });
  }


完整片段

class _TFTState extends State<TFT> {
  Map<String, String>? _defaultCountryCode;
  late List<Map<String, String>> jsonResult;

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

  Future<void> loadJsonData() async {
    /// 
    String data = await rootBundle.loadString('assets/country_code.json');
    final jsonString = jsonDecode(data) as List;

    final item = jsonString.map((e) {
      return {
        'name': e['name'] as String,
        'dial_code': e['dial_code'] as String,
        'code': e['code'] as String,
      };
    }).toList();

    setState(() {
      jsonResult = item;
    });
  }

  final phoneController = TextEditingController();

  _showModalPhoneWidget() {
    showModalBottomSheet(
        backgroundColor: Colors.green,
        context: context,
        isDismissible: true,
        //transitionAnimationController: Duration(milliseconds: 400),
        builder: (context) {
          return StatefulBuilder(
            builder: (context, setStateSTB) => ClipRRect(
              borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(10.0),
                  topRight: Radius.circular(10.0)),
              child: Container(
                height: 250,
                color: Colors.white,
                child: Column(
                  children: <Widget>[
                    Padding(
                      padding: EdgeInsets.only(top: 10.0),
                      child: Text(
                        "Update Phone",
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          color: Colors.black,
                          fontSize: 18.0,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                    Padding(
                      padding: EdgeInsets.only(top: 20.0, left: 10.0),
                      child: Row(
                        children: <Widget>[
                          Text(
                            "Tel No",
                            style:
                                TextStyle(color: Colors.black, fontSize: 15.0),
                          ),
                          Text(
                            "*",
                            style: TextStyle(color: Colors.red, fontSize: 15.0),
                          ),
                        ],
                      ),
                    ),
                    Container(
                      margin:
                          EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
                      height: 50.0,
                      width: double.infinity,
                      decoration: BoxDecoration(
                          color: Colors.white,
                          border: Border.all(color: const Color(0xffededed))),
                      child: Row(
                        children: <Widget>[
                          DropdownButtonHideUnderline(
                            child: ButtonTheme(
                              alignedDropdown: true,
                              child: DropdownButton<Map<String, String>>(
                                value: _defaultCountryCode,
                                hint: Text("Hint textOn null"),
                                items: jsonResult.map((element) {
                                  return DropdownMenuItem(
                                    child: Text(
                                        "${element['name']} ${element['dial_code']}"),
                                    value: element,
                                  );
                                }).toList(),
                                onChanged: (_selectedCountryCode) {
                                  //* to change on dialog
                                  setStateSTB(() {
                                    _defaultCountryCode = _selectedCountryCode;
                                  });

                                  //* to change on StateLevel
                                  setState(() {
                                    _defaultCountryCode = _selectedCountryCode;
                                  });
                                },
                              ),
                            ),
                          ),
                          Container(
                            width: 250,
                            height: 40,
                            child: TextField(
                              controller: phoneController,
                              textAlign: TextAlign.start,
                              decoration: InputDecoration(
                                border: InputBorder.none,
                                hintText: 'Tel No. Ex:0133333333',
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                    Container(
                      margin: EdgeInsets.all(20.0),
                      child: ButtonTheme(
                        minWidth: double.infinity,
                        height: 50,
                        child: OutlineButton(
                          child: Text("Continue",
                              style:
                                  TextStyle(color: Colors.amber, fontSize: 16)),
                          borderSide: BorderSide(
                            color: Colors.amber,
                          ),
                          highlightElevation: 10.0,
                          onPressed: () {},
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          );
        });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          ElevatedButton(
            onPressed: () {
              // json loaded on initState
              print(jsonResult.length);
              _showModalPhoneWidget();
            },
            child: Text("s"),
          )
        ],
      ),
    );
  }
}


推荐阅读