我正在使用Flutter开发移动应用程序。我正在创建一个包含两个字段“选择”或“DropdownButton”的注册页面。
DropdownButton包含按名称列出的国家/地区列表。另一个DropdownButton是国家/地区电话代码的列表。
预期的功能是,当我选择一个国家/地区时,在电话代码的DropdownButton中,它将立即使用所选国家/地区的电话代码进行更新。
这是我使用的变量:

List<DropdownMenuItem<String>> countryList = [];//  Country list
  List<DropdownMenuItem<String>> codeList = [];//  Code list

  String selectedcountries; // Value of the selected country
  String selectedcode; // value of the selected phone code
以下是适用于国家/地区的DropdownButton小部件:
DropdownButton(
                        isExpanded: true,
                        hint: Text('Pais'),
                        items: countryList, // list of countries
                        value: selectedcountries, // value selected of countries
                        onChanged: (value) {
                          setState(() {
                            selectedcountries = value;// here I updated the value of countries
                            selectedcode = value; // here I updated the value of phone code
                          });
                        },
                        style: TextStyle(color: Colors.grey[600], fontSize: 22),
                      ),
这是电话代码的DropdownButton小部件:
DropdownButton(
                            hint: Text('Cod.'),
                            items: codeList, // list of phone codes
                            value: selectedcode, // value of selected phone code
                            onChanged: (value) {
                              setState(() {
                                selectedcode = value;// Here i updated the value of phone code
                              });
                            },
                            style: TextStyle(
                                color: Colors.grey[600], fontSize: 22),
                          ),
我创建了一个函数,该函数加载执行与用户注册相关的功能所需的所有数据:
  Future<void> setInitRegister() async {
    objcifrado = Funcionesgenerales();
    objpaises = await objcifrado.getCountriesData();
    passwordprefix = await objcifrado.getPasswordprefix();
    urlapi = await objcifrado.getPasswordUrl();
    objdata = await objcifrado.getPhoneData();
    objapi = Requestapi(url: urlapi, passwordprefix: passwordprefix);

    loadcountryList();// Load countries list
    loadccodeList();// Load phone code list
    print(countryList);
  }
接下来,有一些功能可以加载国家列表和电话代码。
//From the array of countries I add elements to countrylist
  void loadcountryList() {
    objpaises.forEach((element) {
      countryList.add(new DropdownMenuItem(
        child: new Text(element.name),
        value: element.countrycode,
      ));
    });
  }
//From the array of countries I add elements to codelist
  void loadccodeList() {
    objpaises.forEach((element) {
      codeList.add(new DropdownMenuItem(
        child: new Text(element.phonecode),
        value: element.countrycode,
      ));
    });
  }
setInitRegister函数在呈现之前调用了它,如下所示:
flutter - Flutter:DropdownButton不起作用,我加载了数据,但没有出现在界面中-LMLPHP
这是用户注册屏幕,当我单击选择的“国家”(国家)时。
没发生什么事。当我触摸选择的电话代码(密码)时,也没有任何反应
flutter - Flutter:DropdownButton不起作用,我加载了数据,但没有出现在界面中-LMLPHP
检查控制台,我打印列表。显然,数据可以很好地到达并且没有问题。
flutter - Flutter:DropdownButton不起作用,我加载了数据,但没有出现在界面中-LMLPHP
这是完整的用户注册类别
import 'package:flutter/material.dart';
import 'package:pinfamilyapp/pages/funciones.dart';
import 'package:pinfamilyapp/pages/phonedata.dart';
import 'package:pinfamilyapp/services/servicios.dart';

class Register extends StatefulWidget {
  @override
  _RegisterState createState() => _RegisterState();
}

class _RegisterState extends State<Register> {
  final _formKey = GlobalKey<FormState>();
  bool _autoValidate = false;
  bool obscureText = true;
  bool obscureText2 = true;
  String name;
  String apellidos;
  String telefono;
  String correo;
  String clave;
  String clave2;
  String passwordprefix;
  String urlapi;
  List<Paises> objpaises = [];
  Funcionesgenerales objcifrado;
  Requestapi objapi;
  List<DropdownMenuItem<String>> countryList = []; //  Country list
  List<DropdownMenuItem<String>> codeList = []; //  Code list
  Phonedata objdata;
  String selectedcountries; // Value of the selected country
  String selectedcode; // value of the selected code
  @override
  Widget build(BuildContext context) {
    setInitRegister();
    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
          child: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            SizedBox(height: 20),
            Container(
              padding: EdgeInsets.fromLTRB(5, 10, 10, 10),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.start,
                children: <Widget>[
                  FlatButton(
                      onPressed: () {
                        Navigator.pushReplacementNamed(context, "/home");
                      },
                      child: Icon(
                        Icons.arrow_back,
                        color: Colors.blue[900],
                        size: 25,
                      )),
                  SizedBox(width: 30),
                  Text(
                    "Regístrarse",
                    style: TextStyle(
                        color: Colors.blue[900],
                        fontSize: 22,
                        fontWeight: FontWeight.bold),
                  )
                ],
              ),
            ),
            SizedBox(height: 10),
            Padding(
              padding: EdgeInsets.fromLTRB(30, 5, 30, 5),
              child: Form(
                  key: _formKey,
                  autovalidate: _autoValidate,
                  child: Column(
                    children: <Widget>[
                      TextFormField(
                          onChanged: (val) {
                            setState(() {
                              name = val;
                            });
                          },
                          decoration: InputDecoration(hintText: "Nombres"),
                          style:
                              TextStyle(color: Colors.grey[600], fontSize: 22),
                          validator: (value) {
                            if (value.isEmpty) {
                              return 'Por favor ingrese su(s) Nombre(s)';
                            } else {
                              if (value.length < 4)
                                return 'El nombre debe tener mas de 4 caracteres';
                            }
                            return null;
                          }),
                      SizedBox(height: 10),
                      TextFormField(
                          onChanged: (val) {
                            setState(() {
                              apellidos = val;
                            });
                          },
                          decoration: InputDecoration(hintText: "Apellidos"),
                          style:
                              TextStyle(color: Colors.grey[600], fontSize: 22),
                          validator: (value) {
                            if (value.isEmpty) {
                              return 'Por favor ingrese su(s) Apellido(s)';
                            } else {
                              if (value.length < 4)
                                return 'El apellido debe tener mas de 4 caracteres';
                            }
                            return null;
                          }),
                      SizedBox(height: 10),
                      DropdownButton(
                        isExpanded: true,
                        hint: Text('Pais'),
                        items: countryList,
                        value: selectedcountries,
                        onChanged: (value) {
                          setState(() {
                            selectedcountries = value;
                            selectedcode = value;
                          });
                        },
                        style: TextStyle(color: Colors.grey[600], fontSize: 22),
                      ),
                      SizedBox(height: 10),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.start,
                        verticalDirection: VerticalDirection.down,
                        crossAxisAlignment: CrossAxisAlignment.end,
                        children: <Widget>[
                          DropdownButton(
                            hint: Text('Cod.'),
                            items: codeList,
                            value: selectedcode,
                            onChanged: (value) {
                              setState(() {
                                selectedcode = value;
                              });
                            },
                            style: TextStyle(
                                color: Colors.grey[600], fontSize: 22),
                          ),
                          SizedBox(
                            width: 275,
                            child: TextFormField(
                                onChanged: (val) {
                                  setState(() {
                                    telefono = val;
                                  });
                                },
                                decoration:
                                    InputDecoration(hintText: "Telefono"),
                                keyboardType: TextInputType.phone,
                                style: TextStyle(
                                    color: Colors.grey[600], fontSize: 22),
                                validator: (value) {
                                  if (value.isEmpty) {
                                    return 'Por favor ingrese su telefono';
                                  } else {
                                    if (value.length < 8)
                                      return 'El numero de telefono debe tener mas de 8 digitos';
                                  }
                                  return null;
                                }),
                          ),
                        ],
                      ),
                      SizedBox(height: 10),
                      TextFormField(
                        keyboardType: TextInputType.emailAddress,
                        onChanged: (val) {
                          setState(() {
                            correo = val;
                          });
                        },
                        decoration:
                            InputDecoration(hintText: "Correo electrónico"),
                        style: TextStyle(color: Colors.grey[600], fontSize: 22),
                        validator: (value) {
                          if (value.isEmpty) {
                            return 'Por favor ingrese su correo electrónico';
                          } else {
                            Pattern pattern =
                                r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
                            RegExp regex = new RegExp(pattern);
                            if (!regex.hasMatch(value)) {
                              return 'Por favor ingrese un correo electrónico valido';
                            }
                          }
                          return null;
                        },
                      ),
                      SizedBox(height: 10),
                      TextFormField(
                        onChanged: (val) {
                          setState(() {
                            clave = val;
                          });
                        },
                        obscureText: obscureText,
                        decoration: InputDecoration(
                            hintText: "Contraseña",
                            suffixIcon: GestureDetector(
                              onTap: () {
                                setState(() {
                                  obscureText = !obscureText;
                                });
                              },
                              child: Icon(obscureText
                                  ? Icons.visibility
                                  : Icons.visibility_off),
                            )),
                        style: TextStyle(color: Colors.grey[600], fontSize: 22),
                        validator: (value) {
                          if (value.isEmpty) {
                            return 'Por favor ingrese su contraseña';
                          } else {
                            Pattern pattern =
                                r'(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{6,})$';
                            RegExp regex = new RegExp(pattern);
                            if (!regex.hasMatch(value)) {
                              return 'Por favor ingrese una contraseña valida: \nDebe tener letras y numero, minimo 6 caracteres';
                            }
                          }
                          return null;
                        },
                      ),
                      SizedBox(height: 10),
                      TextFormField(
                        onChanged: (val) {
                          setState(() {
                            clave = val;
                          });
                        },
                        obscureText: obscureText2,
                        decoration: InputDecoration(
                            hintText: "Repetir Contraseña",
                            suffixIcon: GestureDetector(
                              onTap: () {
                                setState(() {
                                  obscureText2 = !obscureText2;
                                });
                              },
                              child: Icon(obscureText2
                                  ? Icons.visibility
                                  : Icons.visibility_off),
                            )),
                        style: TextStyle(color: Colors.grey[600], fontSize: 22),
                        validator: (value) {
                          if (value.isEmpty) {
                            return 'Por favor ingrese su contraseña';
                          } else {
                            Pattern pattern =
                                r'(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{6,})$';
                            RegExp regex = new RegExp(pattern);
                            if (!regex.hasMatch(value)) {
                              return 'Por favor ingrese una contraseña valida: \nDebe tener letras y numero, minimo 6 caracteres';
                            }
                          }
                          return null;
                        },
                      ),
                      SizedBox(
                        height: 25,
                      ),
                      SizedBox(
                        width: 350,
                        child: ButtonTheme(
                          minWidth: 150.0,
                          height: 50.0,
                          child: RaisedButton(
                            color: Colors.green[500],
                            shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(5.0),
                            ),
                            onPressed: () {
                              if (_formKey.currentState.validate()) {
                                // If the form is valid, display a Snackbar.
                                print(name);
                              }
                            },
                            child: Padding(
                              padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
                              child: Text(
                                "Registrarse",
                                style: TextStyle(
                                    color: Colors.white, fontSize: 22),
                              ),
                            ),
                          ),
                        ),
                      )
                    ],
                  )),
            ),
            SizedBox(
              height: 10,
            ),
            Container(
              color: Colors.grey[100],
              child: Padding(
                padding: EdgeInsets.fromLTRB(10, 20, 10, 20),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    SizedBox(height: 20),
                    Center(
                      child: Text(
                        "o Iniciar sesión con:",
                        style:
                            TextStyle(fontSize: 20.0, color: Colors.blue[900]),
                      ),
                    ),
                    SizedBox(height: 20),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        ButtonTheme(
                          minWidth: 150.0,
                          height: 50.0,
                          child: RaisedButton(
                            shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(5.0),
                            ),
                            onPressed: () {},
                            color: Colors.blue[900],
                            child: Padding(
                              padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
                              child: Text(
                                "Facebook",
                                style: TextStyle(
                                    color: Colors.white, fontSize: 22),
                              ),
                            ),
                          ),
                        ),
                        SizedBox(width: 10),
                        ButtonTheme(
                          minWidth: 150.0,
                          height: 50.0,
                          child: RaisedButton(
                            shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(5.0),
                            ),
                            onPressed: () {},
                            color: Colors.red[500],
                            child: Padding(
                              padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
                              child: Text(
                                "Google +",
                                style: TextStyle(
                                    color: Colors.white, fontSize: 22),
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                    SizedBox(height: 20)
                  ],
                ),
              ),
            ),
            Container(
              color: Colors.blue[900],
              height: 70,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text("¿Ya tienes cuenta?",
                      style: TextStyle(color: Colors.white, fontSize: 20)),
                  SizedBox(width: 1),
                  FlatButton(
                      onPressed: () {
                        Navigator.pushReplacementNamed(context, "/home");
                      },
                      child: Text(
                        "Iniciar sesión",
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 20,
                          decoration: TextDecoration.underline,
                        ),
                      ))
                ],
              ),
            )
          ],
        ),
      )),
    );
  }

  Future<void> setInitRegister() async {
    objcifrado = Funcionesgenerales();
    objpaises = await objcifrado.getCountriesData();
    passwordprefix = await objcifrado.getPasswordprefix();
    urlapi = await objcifrado.getPasswordUrl();
    objdata = await objcifrado.getPhoneData();
    objapi = Requestapi(url: urlapi, passwordprefix: passwordprefix);

    loadcountryList();// Load countries list
    loadccodeList();// Load phone code list
    print(countryList);
  }

//From the array of countries I add elements to countrylist
  void loadcountryList() {
    objpaises.forEach((element) {
      countryList.add(new DropdownMenuItem(
        child: new Text(element.name),
        value: element.countrycode,
      ));
    });
  }
//From the array of countries I add elements to codelist
  void loadccodeList() {
    objpaises.forEach((element) {
      codeList.add(new DropdownMenuItem(
        child: new Text(element.phonecode),
        value: element.countrycode,
      ));
    });
  }
}
有任何想法吗?

最佳答案

好像很好
一个想法..表格可能在 setInitRegister完成之前正在加载
你可以试试吗?

class _RegisterState extends State<Register> {
  final _formKey = GlobalKey<FormState>();
  bool _autoValidate = false;
  ...

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: FutureBuilder<Map>(
          future: setInitRegister(),
          builder: (BuildContext context, snapshot) {
            if (!snapshot.hasData) {
              // while data is loading:
              return Center(
                child: CircularProgressIndicator(),
              );
            } else {
              // data loaded:
              final Map data = snapshot.data;
              final List<DropdownMenuItem<String>> countryList = data['countryList'];
              final List<DropdownMenuItem<String>> codeList = data['codeList'];
              return Center(
                child: SafeArea( ... ),
              );
            }
          },
        ),
  }

  Future<Map> setInitRegister() async {
    List<DropdownMenuItem<String>> countryList;
    List<DropdownMenuItem<String>> codeList;
    Map result = {};

    objcifrado = Funcionesgenerales();
    List<Paises> objpaises = await objcifrado.getCountriesData();
    passwordprefix = await objcifrado.getPasswordprefix();
    urlapi = await objcifrado.getPasswordUrl();
    objdata = await objcifrado.getPhoneData();
    objapi = Requestapi(url: urlapi, passwordprefix: passwordprefix);

    countryList = loadcountryList(objpaises);// Load countries list
    codeList = loadccodeList(objpaises);// Load phone code list

    result['countryList'] = countryList;
    result['codeList'] = codeList;

    return result;
  }

  //From the array of countries I add elements to countrylist
  List<DropdownMenuItem<String>> loadcountryList(List<Paises> objpaises) {
    List<DropdownMenuItem<String>> countryList = [];
    objpaises.forEach((element) {
      countryList.add(new DropdownMenuItem(
        child: new Text(element.name),
        value: element.countrycode,
      ));
    });

    return countryList;
  }

  //From the array of countries I add elements to codelist
  List<DropdownMenuItem<String>> loadccodeList(List<Paises> objpaises) {
    List<DropdownMenuItem<String>> codeList = [];
    objpaises.forEach((element) {
      codeList.add(new DropdownMenuItem(
        child: new Text(element.phonecode),
        value: element.countrycode,
      ));
    });
    return codeList;
  }


}
您也可以检查this post,其中大部分答案都基于我。
更好的解决方案是将将来的调用移到initState中(同样,请参见文章);但我首先尝试保持简单。
让我知道事情的后续!

关于flutter - Flutter:DropdownButton不起作用,我加载了数据,但没有出现在界面中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62999365/

10-11 09:14