J'ai une liste d'emplacements que je veux implémenter en tant que liste déroulante dans Flutter. Je suis assez nouveau dans la langue. Voici ce que j'ai fait.
new DropdownButton(
value: _selectedLocation,
onChanged: (String newValue) {
setState(() {
_selectedLocation = newValue;
});
},
items: _locations.map((String location) {
return new DropdownMenuItem<String>(
child: new Text(location),
);
}).toList(),
Ceci est ma liste d'articles:
List<String> _locations = ['A', 'B', 'C', 'D'];
Et j'obtiens l'erreur suivante.
Another exception was thrown: 'package:flutter/src/material/dropdown.Dart': Failed assertion: line 468 pos 15: 'value == null || items.where((DropdownMenuItem<T> item) => item.value == value).length == 1': is not true.
Je suppose que la valeur de _selectedLocation
devient nulle. Mais je l'initialise comme ça.
String _selectedLocation = 'Please choose a location';
Essaye ça
new DropdownButton<String>(
items: <String>['A', 'B', 'C', 'D'].map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (_) {},
)
Vous devez ajouter value: location
dans votre code pour le faire fonctionner. Vérifiez this out.
items: _locations.map((String location) {
return new DropdownMenuItem<String>(
child: new Text(location),
value: location,
);
}).toList(),
vous devez en tenir compte (à partir de la documentation DropdownButton):
"Les éléments doivent avoir des valeurs distinctes et si la valeur n’est pas nulle, il faut Être parmi eux."
Donc, fondamentalement, vous avez cette liste de chaînes
List<String> _locations = ['A', 'B', 'C', 'D'];
Et votre valeur dans la propriété de valeur Dropdown est initialisée comme ceci:
String _selectedLocation = 'Please choose a location';
Essayez juste avec cette liste:
List<String> _locations = ['Please choose a location', 'A', 'B', 'C', 'D'];
Cela devrait fonctionner :)
Consultez également la propriété "hint" si vous ne souhaitez pas ajouter une chaîne comme celle-ci (en dehors du contexte de la liste), vous pouvez utiliser quelque chose comme ceci:
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(() {});
});
placez la valeur à l'intérieur des éléments.Ensuite, cela fonctionnera,
new DropdownButton<String>(
items:_dropitems.map((String val){
return DropdownMenuItem<String>(
value: val,
child: new Text(val),
);
}).toList(),
hint:Text(_SelectdType),
onChanged:(String val){
_SelectdType= val;
setState(() {});
})
Tout d’abord, examinons ce que dit l’erreur (j’ai cité l’erreur commise avec Flutter 1.2, mais l’idée est la même):
Échec de l'assertion: ligne 560, position 15: 'items == null || items.isEmpty || valeur == null || items.where ((DropdownMenuItem item) => item.value == valeur) .length == 1 ': n'est pas vrai.
Il existe quatre conditions or
. Au moins l'un d'entre eux doit être rempli:
DropdownMenuItem
widgets) ont été fournis. Ceci élimine items == null
.items.isEmpty
._selectedLocation
) a également été donnée. Ceci élimine value == null
. Notez qu'il s'agit de la valeur de DropdownButton
et non de DropdownMenuItem
.Par conséquent, il ne reste que le dernier contrôle. Cela revient à quelque chose comme:
Parcourez
DropdownMenuItem
's. Trouvez tous ceux qui ont unevalue
égale à_selectedLocation
. Ensuite, vérifiez combien d’éléments correspondants ont été trouvés. Il doit y avoir exactement un widget qui a cette valeur. Sinon, jetez une erreur.
Le code de manière est présenté, il n'y a pas de widget DropdownMenuItem
qui a la valeur _selectedLocation
. Au lieu de cela, la valeur de null
est définie pour tous les widgets. Depuis null != _selectedLocation
, la dernière condition échoue. Vérifiez cela en définissant _selectedLocation
sur null
- l'application doit s'exécuter.
Pour résoudre le problème, nous devons d’abord définir une valeur pour chaque DropdownMenuItem
(afin que quelque chose puisse être passé au rappel onChanged
):
return DropdownMenuItem(
child: new Text(location),
value: location,
);
L'application échouera toujours. En effet, votre liste ne contient toujours pas la valeur de _selectedLocation
. Vous pouvez faire en sorte que l'application fonctionne de deux manières:
items.where((DropdownMenuItem<T> item) => item.value == value).length == 1
). Cela peut être utile si vous souhaitez laisser l'utilisateur sélectionner à nouveau l'option Please choose a location
.hint:
paremter et définissez selectedLocation
sur null
(pour satisfaire à la condition value == null
). Utile si vous ne voulez pas que Please choose a location
reste une option.Voir le code ci-dessous qui montre comment faire:
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(),
),
),
),
);
}
}
Disons que nous créons une liste déroulante de devise:
List _currency = ["INR", "USD", "SGD", "EUR", "PND"];
List<DropdownMenuItem<String>> _dropDownMenuCurrencyItems;
String _currentCurrency;
List<DropdownMenuItem<String>> getDropDownMenuCurrencyItems() {
List<DropdownMenuItem<String>> items = new List();
for (String currency in _currency) {
items.add(
new DropdownMenuItem(value: currency, child: new Text(currency)));
}
return items;
}
void changedDropDownItem(String selectedCurrency) {
setState(() {
_currentCurrency = selectedCurrency;
});
}
Ajouter ci-dessous le code dans la partie du corps:
new Row(children: <Widget>[
new Text("Currency: "),
new Container(
padding: new EdgeInsets.all(16.0),
),
new DropdownButton(
value: _currentCurrency,
items: _dropDownMenuCurrencyItems,
onChanged: changedDropDownItem,
)
])
Lorsque je me suis posé le problème de vouloir un DropdownStringButton moins générique, je l'ai simplement créé:
dropdown_string_button.Dart
import 'package:flutter/material.Dart';
// Subclass of DropdownButton based on String only values.
// Yes, I know Flutter discourages subclassing, but this seems to be
// a reasonable exception where a commonly used specialization can be
// made more easily usable.
//
// Usage:
// DropdownStringButton(items: ['A', 'B', 'C'], value: 'A', onChanged: (string) {})
//
class DropdownStringButton extends DropdownButton<String> {
DropdownStringButton({
Key key, @required List<String> items, value, hint, disabledHint,
@required onChanged, elevation = 8, style, iconSize = 24.0, isDense = false,
isExpanded = false, }) :
assert(items == null || value == null || items.where((String item) => item == value).length == 1),
super(
key: key,
items: items.map((String item) {
return DropdownMenuItem<String>(child: Text(item), value: item);
}).toList(),
value: value, hint: hint, disabledHint: disabledHint, onChanged: onChanged,
elevation: elevation, style: style, iconSize: iconSize, isDense: isDense,
isExpanded: isExpanded,
);
}
L'erreur que vous obtenez est due à demander une propriété d'un objet null. Votre élément doit être nul. Ainsi, lorsque vous demandez la comparaison de sa valeur, vous obtenez cette erreur. Vérifiez que vous obtenez des données ou que votre liste est une liste d'objets et non de simples chaînes.
J'étais confronté à un problème similaire avec DropDownButton lorsque j'essayais d'afficher une liste dynamique de chaînes dans la liste déroulante. J'ai fini par créer un plugin: flutter_search_panel . Pas un plugin déroulant, mais vous pouvez afficher les éléments avec la fonctionnalité de recherche.
Utilisez le code suivant pour utiliser le widget:
FlutterSearchPanel(
padding: EdgeInsets.all(10.0),
selected: 'a',
title: 'Demo Search Page',
data: ['This', 'is', 'a', 'test', 'array'],
icon: new Icon(Icons.label, color: Colors.black),
color: Colors.white,
textStyle: new TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20.0, decorationStyle: TextDecorationStyle.dotted),
onChanged: (value) {
print(value);
},
),