Solución:
Prueba esto
new DropdownButton<String>(
items: <String>['A', 'B', 'C', 'D'].map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (_) {},
)
Para la solución, desplácese hasta el final de la respuesta.
En primer lugar, investiguemos lo que dice el error (he citado el error que se produce con Flutter 1.2, pero la idea es la misma):
Aserción fallida: línea 560 pos 15: ‘items == null || items.isEmpty || valor == nulo || items.where ((DropdownMenuItem item) => item.value == value) .length == 1 ‘: no es cierto.
Existen cuatro or
condiciones. Se debe cumplir al menos uno de ellos:
- Elementos (una lista de
DropdownMenuItem
widgets) se proporcionaron. Esto eliminaitems == null
. - Se proporcionó una lista no vacía. Esto elimina
items.isEmpty
. - Un valor (
_selectedLocation
) también se dio. Esto eliminavalue == null
. Tenga en cuenta que esto esDropdownButton
valor, noDropdownMenuItem
valor de.
Por lo tanto, solo queda el último cheque. Se reduce a algo como:
Iterar a través de
DropdownMenuItem
‘s. Encuentra todo lo que tenga unvalue
eso es igual a_selectedLocation
. Luego, verifique cuántos elementos que coinciden con él se encontraron. Debe haber exactamente un widget que tenga este valor. De lo contrario, arroja un error.
La forma en que se presenta el código, no hay un DropdownMenuItem
widget que tiene un valor de _selectedLocation
. En cambio, todos los widgets tienen su valor establecido en null
. Ya que null != _selectedLocation
, la última condición falla. Verifique esto configurando _selectedLocation
para null
– la aplicación debería ejecutarse.
Para solucionar el problema, primero debemos establecer un valor en cada DropdownMenuItem
(para que algo pueda pasarse a onChanged
llamar de vuelta):
return DropdownMenuItem(
child: new Text(location),
value: location,
);
La aplicación seguirá fallando. Esto se debe a que su lista aún no contiene _selectedLocation
valor de. Puede hacer que la aplicación funcione de dos maneras:
-
Opción 1. Agregue otro widget que tenga el valor (para satisfacer
items.where((DropdownMenuItem<T> item) => item.value == value).length == 1
). Puede ser útil si desea que el usuario vuelva a seleccionarPlease choose a location
opción. -
opcion 2. Pasar algo a
hint:
paremter y setselectedLocation
paranull
(satisfacervalue == null
condición). Útil si no quieresPlease choose a location
para seguir siendo una opción.
Vea el código a continuación que muestra cómo hacerlo:
import 'package:flutter/material.dart';
void main() {
runApp(Example());
}
class Example extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
// List<String> _locations = ['Please choose a location', 'A', 'B', 'C', 'D']; // Option 1
// String _selectedLocation = 'Please choose a location'; // Option 1
List<String> _locations = ['A', 'B', 'C', 'D']; // Option 2
String _selectedLocation; // Option 2
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: DropdownButton(
hint: Text('Please choose a location'), // Not necessary for Option 1
value: _selectedLocation,
onChanged: (newValue) {
setState(() {
_selectedLocation = newValue;
});
},
items: _locations.map((location) {
return DropdownMenuItem(
child: new Text(location),
value: location,
);
}).toList(),
),
),
),
);
}
}
tienes que tener esto en cuenta (de los documentos de DropdownButton):
“Los elementos deben tener valores distintos y si el valor no es nulo, debe estar entre ellos”.
Entonces, básicamente tienes esta lista de cadenas
List<String> _locations = ['A', 'B', 'C', 'D'];
Y su valor en la propiedad de valor desplegable se inicializa así:
String _selectedLocation = 'Please choose a location';
Prueba con esta lista:
List<String> _locations = ['Please choose a location', 'A', 'B', 'C', 'D'];
Eso debería funcionar 🙂
También consulte la propiedad “sugerencia” si no desea agregar una Cadena como esa (fuera del contexto de la lista), podría optar por algo como esto:
DropdownButton<int>(
items: locations.map((String val) {
return new DropdownMenuItem<String>(
value: val,
child: new Text(val),
);
}).toList(),
hint: Text("Please choose a location"),
onChanged: (newVal) {
_selectedLocation = newVal;
this.setState(() {});
});