webentwicklung-frage-antwort-db.com.de

Wie implementiert man eine Dropdown-Liste im Flattern?

Ich habe eine Liste von Orten, die ich als Dropdown-Liste in Flutter implementieren möchte. Ich bin ziemlich neu in der Sprache. Hier ist was ich getan habe.

new DropdownButton(
  value: _selectedLocation,
  onChanged: (String newValue) {
    setState(() {
      _selectedLocation = newValue;
     });
},
items: _locations.map((String location) {
  return new DropdownMenuItem<String>(
     child: new Text(location),
  );
}).toList(),

Dies ist meine Artikelliste:

List<String> _locations = ['A', 'B', 'C', 'D'];

Und ich erhalte den folgenden Fehler.

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.

Ich gehe davon aus, dass der Wert von _selectedLocation null wird. Aber ich initialisiere es so.

String _selectedLocation = 'Please choose a location';

17
Chaythanya nair

Versuche dies

new DropdownButton<String>(
  items: <String>['A', 'B', 'C', 'D'].map((String value) {
    return new DropdownMenuItem<String>(
      value: value,
      child: new Text(value),
    );
  }).toList(),
  onChanged: (_) {},
)
17
Pravin Raj

Sie müssen in Ihrem Code value: location hinzufügen, um diese Funktion auszuführen. Überprüfen Sie dies aus.

items: _locations.map((String location) {
  return new DropdownMenuItem<String>(
     child: new Text(location),
     value: location,
  );
}).toList(),
4
DwlRathod

sie müssen dies berücksichtigen (aus DropdownButton-Dokumenten):

Msgstr "Die Elemente müssen unterschiedliche Werte haben, und wenn value nicht null ist, muss Unter ihnen sein."

Im Grunde haben Sie diese Liste von Strings

List<String> _locations = ['A', 'B', 'C', 'D'];

Ihr Wert in der Dropdown-Werteigenschaft wird folgendermaßen initialisiert:

String _selectedLocation = 'Please choose a location';

Versuchen Sie es einfach mit dieser Liste:

List<String> _locations = ['Please choose a location', 'A', 'B', 'C', 'D'];

Das sollte funktionieren :)

Schauen Sie sich auch die "Hinweis" -Eigenschaft an, wenn Sie einen solchen String nicht hinzufügen möchten (außerhalb des Listenkontexts). In diesem Fall könnten Sie Folgendes verwenden:

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(() {});
                  });
3
Rubs

Sie können die Klasse DropDownButton verwenden, um eine Dropdown-Liste zu erstellen:

...
...
String dropdownValue = 'One';
...
...
Widget build(BuildContext context) {
return Scaffold(
  body: Center(
    child: DropdownButton<String>(
      value: dropdownValue,
      onChanged: (String newValue) {
        setState(() {
          dropdownValue = newValue;
        });
      },
      items: <String>['One', 'Two', 'Free', 'Four']
          .map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList(),
    ),
  ),
);
...
...

bitte beziehen Sie sich auf diese flatternde Webseite

2
user4757345

platziere den Wert innerhalb der Items. Dann funktioniert es,

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(() {});
                })
1
Ajit Paul

Es war mir passiert, als ich den Standardwert durch einen neuen dynamischen Wert ersetzte. Aber irgendwie kann Ihr Code von diesem Standardwert abhängen. Versuchen Sie also, einen konstanten Wert mit dem Standardwert beizubehalten, der an einem Ort gespeichert ist, an dem ein Fallback möglich ist.

const defVal = 'abcd';
String dynVal = defVal;

// dropdown list whose value is dynVal that keeps changing with onchanged
// when rebuilding or setState((){})

dynVal = defVal;
// rebuilding here...
0

Lassen Sie uns zunächst untersuchen, was der Fehler sagt (ich habe den mit Flutter 1.2 geworfenen Fehler zitiert, aber die Idee ist die gleiche):

Fehlgeschlagene Assertion: Zeile 560 Pos 15: 'items == null || items.isEmpty || Wert == null || items.where ((DropdownMenuItem-Element) => item.value == value) .length == 1 ': ist nicht wahr.

Es gibt vier or-Bedingungen. Mindestens einer von ihnen muss erfüllt sein:

  • Es wurden Elemente (eine Liste von DropdownMenuItem-Widgets) bereitgestellt. Dies beseitigt items == null.
  • Es wurde eine nicht leere Liste bereitgestellt. Dies beseitigt items.isEmpty.
  • Ein Wert (_selectedLocation) wurde ebenfalls angegeben. Dies beseitigt value == null. Beachten Sie, dass dies der Wert von DropdownButton und nicht von DropdownMenuItem ist.

Daher bleibt nur die letzte Kontrolle übrig. Es läuft auf etwas wie:

Iteriere durch DropdownMenuItem. Finde alle, die eine value haben, die gleich _selectedLocation ist. Prüfen Sie anschließend, wie viele Artikel gefunden wurden. Es muss genau ein Widget geben, das diesen Wert hat. Andernfalls wird ein Fehler ausgegeben.

Bei der Darstellung von Code gibt es kein DropdownMenuItem-Widget mit dem Wert _selectedLocation. Stattdessen ist der Wert aller Widgets auf null gesetzt. Seit null != _selectedLocation schlägt die letzte Bedingung fehl. Überprüfen Sie dies, indem Sie _selectedLocation auf null setzen - die App sollte ausgeführt werden.

Um das Problem zu beheben, müssen wir zunächst einen Wert für jede DropdownMenuItem festlegen (damit etwas an onChanged callback übergeben werden kann):

return DropdownMenuItem(
    child: new Text(location),
    value: location,
);

Die App wird immer noch fehlschlagen. Dies liegt daran, dass Ihre Liste immer noch nicht den Wert von _selectedLocation enthält. Sie können die App auf zwei Arten zum Laufen bringen:

  • Option 1 . Fügen Sie ein weiteres Widget hinzu, das den Wert hat (um items.where((DropdownMenuItem<T> item) => item.value == value).length == 1 zu erfüllen). Kann nützlich sein, wenn der Benutzer die Option Please choose a location erneut auswählen soll.
  • Option 2 . Übergeben Sie etwas an hint: paremter und setzen Sie selectedLocation auf null (um die value == null-Bedingung zu erfüllen). Nützlich, wenn Please choose a location keine Option bleiben soll.

Der Code unten zeigt, wie es geht:

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(),
          ),
        ),
      ),
    );
  }
}
0
cegas

Nehmen wir an, wir erstellen eine Dropdown-Liste mit Währungen:

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;
  });
}

Füge unten Code im Körperteil hinzu:

new Row(children: <Widget>[
  new Text("Currency: "),
  new Container(
    padding: new EdgeInsets.all(16.0),
  ),
  new DropdownButton(
    value: _currentCurrency,
    items: _dropDownMenuCurrencyItems,
    onChanged: changedDropDownItem,
  )
])
0
lavish

Als ich in dieser Ausgabe auf ein weniger generisches DropdownStringButton stieß, habe ich es gerade erstellt:

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,
        );
    }
0
Cirec Beback

Veränderung

List<String> _locations = ['A', 'B', 'C', 'D'];

Zu

List<String> _locations = [_selectedLocation, 'A', 'B', 'C', 'D'];

_selectedLocation muss Teil Ihrer Artikelliste sein.

0
sammyni

Der Fehler, den Sie erhalten, ist auf eine Eigenschaft eines Nullobjekts zurückzuführen. Ihr Artikel muss null sein. Wenn Sie also nach einem Vergleich des Werts fragen, wird dieser Fehler angezeigt. Vergewissern Sie sich, dass Sie Daten erhalten oder dass Ihre Liste eine Liste von Objekten und keine einfachen Zeichenfolgen ist.

0
Matias

Ich hatte ein ähnliches Problem mit dem DropDownButton, als ich versuchte, eine dynamische Liste von Zeichenfolgen in der Dropdown-Liste anzuzeigen. Am Ende habe ich ein Plugin erstellt: flutter_search_panel . Kein Dropdown-Plugin, aber Sie können die Elemente mit der Suchfunktion anzeigen.

Verwenden Sie den folgenden Code für die Verwendung des Widgets:

    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);
        },
   ),
0
dranzer