Flutter: DropdownButton is not working, I load the data but it does not appear in the interface
It seems fine.
One idea.. The Form may be loading before setInitRegister finishes.
Can you try this?:
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;
}
}
You can also check this post in which I based most of my answer.
A slightly better solution would be to move the future call into initState (again, see the post); but I tried to keep it simple first.
Let me know how it goes!

Rivero Felipe
Updated on December 22, 2022Comments
-
Rivero Felipe less than a minute
I am working on a mobile application with Flutter. I am creating a registration page that contains two fields "select" or "DropdownButton".
A DropdownButton contains a list of countries by names. The other DropdownButton is a list of country phone codes.
The expected functionality is when I select a country, in the DropdownButton of telephone codes it is updated immediately with the telephone code of the selected country.
Here are the variables I use:
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
Here is the DropdownButton Widget for countries:
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), ),
Here is the DropdownButton Widget for phone code:
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), ),
I created a function that loads all the data I need to perform the functions associated with user registration:
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); }
Next, there are the functions that load the list of countries and telephone codes.
//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, )); }); }
The setInitRegister function called it before rendering like so:
Here is the user registration screen, when I click on the select "country" (Country).
Nothing happens. Also nothing happens when I touch the select of phone code (Cod.)
Checking the console, I print the lists. Apparently the data arrives well and without problems.
Here is the full class of user registration
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'^(([^<>()[\]\\.,;:\[email protected]\"]+(\.[^<>()[\]\\.,;:\[email protected]\"]+)*)|(\".+\"))@((\[[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, )); }); } }
Any ideas?
-
Rivero Felipe over 2 yearsThank you so much. You answer save me. Now its working perfectly.
-
Andres Silva over 2 yearsMy pleasure! I'm glad it helped.