web-dev-qa-db-ja.com

flutterにドロップダウンリストを実装する方法

Flutterにドロップダウンリストとして実装したい場所のリストがあります。私は言語にかなり新しいです。これが私がやったことです。

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

これは私のアイテムのリストです:

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

そして、次のエラーが表示されます。

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.

_selectedLocationの値がnullになっていると思います。しかし、私はそれをそのように初期化しています。

String _selectedLocation = 'Please choose a location';

27
Chaythanya nair

これを試して

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

まず、エラーの内容を調べてみましょう(Flutter 1.2でスローされるエラーを引用しましたが、考え方は同じです)。

失敗したアサーション:560行目15: 'items == null || items.isEmpty ||値== null || items.where((DropdownMenuItem item)=> item.value == value).length == 1 ':正しくありません。

4つのor条件があります。それらの少なくとも1つを満たす必要があります。

  • アイテム(DropdownMenuItemウィジェットのリスト)が提供されました。これにより、items == nullがなくなります。
  • 空でないリストが提供されました。これにより、items.isEmptyがなくなります。
  • 値(_selectedLocation)も与えられました。これにより、value == nullがなくなります。これはDropdownButtonの値であり、DropdownMenuItemの値ではないことに注意してください。

したがって、最後のチェックのみが残ります。要約すると次のようになります。

DropdownMenuItemを繰り返し処理します。 _selectedLocationと等しいvalueを持つすべてを検索します。次に、一致するアイテムがいくつ見つかったかを確認します。この値を持つウィジェットは1つだけ存在する必要があります。それ以外の場合は、エラーをスローします。

コードの表示方法には、_selectedLocationの値を持つDropdownMenuItemウィジェットはありません。代わりに、すべてのウィジェットの値はnullに設定されています。 null != _selectedLocationなので、最後の条件は失敗します。 _selectedLocationnullに設定してこれを確認します-アプリが実行されます。

この問題を修正するには、最初に各DropdownMenuItemに値を設定する必要があります(何かがonChangedコールバックに渡されるように):

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

アプリは引き続き失敗します。これは、リストに_selectedLocationの値がまだ含まれていないためです。次の2つの方法でアプリを機能させることができます。

  • オプション1。 (items.where((DropdownMenuItem<T> item) => item.value == value).length == 1を満たすために)値を持つ別のウィジェットを追加します。ユーザーがPlease choose a locationオプションを再選択できるようにする場合に便利です。
  • オプション2hint:パラメーターに何かを渡し、selectedLocationnullに設定します(value == null条件を満たすため)。 Please choose a locationをオプションのままにしたくない場合に便利です。

その方法を示す以下のコードを参照してください。

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

これを考慮する必要があります(DropdownButtonドキュメントから):

「アイテムには個別の値が必要です。値がnullでない場合は、アイテムに含まれている必要があります。」

基本的に、この文字列のリストがあります

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

そして、ドロップダウン値プロパティの値は次のように初期化されます。

String _selectedLocation = 'Please choose a location';

このリストを試してください:

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

それは動作するはずです:)

また、(リストコンテキストから)そのような文字列を追加したくない場合は、「ヒント」プロパティを確認してください。次のようなものを使用できます。

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

動作させるには、コードにvalue: locationを追加する必要があります。 this outを確認してください。

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

アイテム内に値を配置します。それが機能します。

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

ドロップダウンリストを作成するためにDropDownButtonクラスを使用できます:

...
...
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(),
    ),
  ),
);
...
...

これを参照してください flutter web page

2
user4757345

デフォルト値を新しい動的な値に置き換えたときに、それが私に起こりました。しかし、どういうわけかあなたのコードはそのデフォルト値に依存しているかもしれません。したがって、フォールバックするためにどこかに保存されているデフォルト値で定数を維持してみてください。

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

通貨のドロップダウンリストを作成しているとしましょう:

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

本文部分に以下のコードを追加:

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

あまり一般的ではないDropdownStringButtonが欲しいというこの問題に遭遇したとき、私はそれを作成しました:

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

変化する

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

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

_selectedLocationは、アイテムリストの一部である必要があります。

0
sammyni

取得しているエラーは、nullオブジェクトのプロパティを要求することが原因です。あなたのアイテムはnullでなければならないので、その値を比較するように頼むとき、あなたはそのエラーを得ています。データを取得していること、またはリストがオブジェクトのリストであり、単純な文字列ではないことを確認してください。

0
Matias

ドロップダウンで文字列の動的リストを表示しようとしたときに、DropDownButtonで同様の問題に直面していました。プラグインを作成することになった: flutter_search_panel 。ドロップダウンプラグインではありませんが、検索機能を使用してアイテムを表示できます。

ウィジェットを使用するには、次のコードを使用します。

    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