Flutterドロップダウンに問題があります。アイテムの1つを選択すると、エラーがスローされます。
別の例外がスローされました: 'package:flutter/src/material/dropdown.Dart':失敗したアサーション:481行目15: 'value == null || items.where((DropdownMenuItem item)=> item.value == value).length == 1 ':真ではありません。
私は検索していて、選択した要素が元のリストに属していないためにこのエラーが発生したと人々は言うが、デバッグの後でそれを確認できます。私はこのエラーの原因を見つけることができないので、私はどんな助けにも感謝します。
これが私のコードです
FeedCategoryモデル
import 'package:meta/meta.Dart';
class FeedCategory {
static final dbId = "id";
static final dbName = "name";
int id;
String name;
FeedCategory({this.id, @required this.name});
FeedCategory.fromMap(Map<String, dynamic> map)
: this(
id: map[dbId],
name: map[dbName],
);
Map<String, dynamic> toMap() {
return {
dbId: id,
dbName: name,
};
}
@override
String toString() {
return 'FeedCategory{id: $id, name: $name}';
}
}
ウィジェット
import 'package:app2date/repository/repository.Dart';
import 'package:app2date/model/FeedSource.Dart';
import 'package:app2date/model/FeedCategory.Dart';
import 'package:app2date/util/ui.Dart';
import 'package:flutter/material.Dart';
class ManageFeedSource extends StatefulWidget {
ManageFeedSource({Key key, this.feedSource}) : super(key: key);
final FeedSource feedSource;
@override
_ManageFeedSource createState() => new _ManageFeedSource();
}
class _ManageFeedSource extends State<ManageFeedSource> {
FeedCategory _feedCategory;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('New Feed'),
),
body: new FutureBuilder(
future: Repository.get().getFeedCategories(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
List<FeedCategory> categoriesList = snapshot.data;
if (categoriesList != null) {
return new DropdownButton<FeedCategory>(
hint: Text('Choose category...'),
value: _feedCategory,
items: categoriesList.map((FeedCategory category) {
return DropdownMenuItem<FeedCategory>(
value: category,
child: Text(category.name),
);
}).toList(),
onChanged: (FeedCategory category) {
print('Selected: $category');
setState(() {
_feedCategory = category;
});
},
);
} else {
return Container(
decoration: new BoxDecoration(color: Colors.white),
);
}
},
),
);
}
@override
void initState() {
super.initState();
}
}
リポジトリのgetFeedCategoriesメソッド
Future<List<FeedCategory>> getFeedCategories() async {
return await database.getFeedCategories();
}
データベースのgetFeedCategoriesメソッド
Future<List<FeedCategory>> getFeedCategories() async {
var dbClient = await db;
var query = "SELECT * FROM $feedCategoryTableName;";
var result = await dbClient.rawQuery(query);
List<FeedCategory> feedCategories = [];
for (Map<String, dynamic> item in result) {
feedCategories.add(new FeedCategory.fromMap(item));
}
return feedCategories;
}
私はあなたの問題を理解したと思います。これは、FutureBuilderの使用方法に由来しています。
これは私が起こっていると思うことです:
未来が完成し、次の項目でリストが作成されます。
obj 123 ==> FeedCategory(Prueba)
、obj 345 ==> FeedCategory(Categories 2)
ドロップダウンからアイテムを選択すると、setState()が呼び出されます
_ feedCategoryがobj 123 ==> FeedCategory(Prueba)
と等しくなりました
ウィジェットが再構築されます。 getFeedCategories()への別の呼び出しを行います
将来の完成、リストの作成などは次の項目で
obj 567 ==> FeedCategory(Prueba)
、obj 789 ==> FeedCategory(Categories 2)
items.where((DropdownMenuItem item) => item.value == value).length == 1
をテストしますが、obj 123 ==> FeedCategory(Prueba)
が見つからないため、長さ== 0です。あなたの問題にはいくつかの解決策があります。 1つは、カテゴリやIDを比較するFeedCategory
クラスに equals operator を追加することです。
もう1つは、futurebuilderで使用されるFutureを変更する部分から分離することです。これは、futureをメンバー変数として保持する(おそらくinitStateでインスタンス化する)か、ビルダーの内部をそれに変更することで実行できます。独自のステートフルウィジェット(この場合、おそらくManageFeedSourceをStatelessWidgetにすることができます)。最後のオプションをお勧めします。
それでも問題が解決しない場合はお知らせください。それが、実際に問題が発生している理由だと確信しています。
rmtmckenzie answer を完了するには、FeedCategoryオブジェクトに挿入する必要があるコードを次に示します。
bool operator ==(o) => o is FeedCategory && o.name == name;
int get hashCode => name.hashCode;
編集:FlutterでhashCodeがどのように作成されるかを説明する link
エラーメッセージからは不明なドロップダウンリストに実際にはない値でドロップダウンを初期化したときに、このエラーが発生しました。