Cha*_*air 33 dart drop-down-menu 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(),
Run Code Online (Sandbox Code Playgroud)
这是我的项目清单:
List<String> _locations = ['A', 'B', 'C', 'D'];
Run Code Online (Sandbox Code Playgroud)
我收到以下错误.
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.
Run Code Online (Sandbox Code Playgroud)
我假设值为_selectedLocationnull.但我正在初始化它.
String _selectedLocation = 'Please choose a location';
小智 38
试试这个
new DropdownButton<String>(
items: <String>['A', 'B', 'C', 'D'].map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (_) {},
)
Run Code Online (Sandbox Code Playgroud)
Ali*_*ice 17
使用StatefulWidget和setState更新下拉列表。
String _dropDownValue;
@override
Widget build(BuildContext context) {
return DropdownButton(
hint: _dropDownValue == null
? Text('Dropdown')
: Text(
_dropDownValue,
style: TextStyle(color: Colors.blue),
),
isExpanded: true,
iconSize: 30.0,
style: TextStyle(color: Colors.blue),
items: ['One', 'Two', 'Three'].map(
(val) {
return DropdownMenuItem<String>(
value: val,
child: Text(val),
);
},
).toList(),
onChanged: (val) {
setState(
() {
_dropDownValue = val;
},
);
},
);
}
Run Code Online (Sandbox Code Playgroud)
下拉的初始状态:
打开下拉菜单并选择值:
将选定的值反映到下拉列表中:
Doa*_*Bui 17
如果您不想像Drop list弹出窗口一样显示。您可以像我一样以这种方式自定义它(它会像在同一个平面上一样显示,见下图):
展开后:
请按照以下步骤操作: 首先,创建一个名为 的 dart 文件drop_list_model.dart:
import 'package:flutter/material.dart';
class DropListModel {
DropListModel(this.listOptionItems);
final List<OptionItem> listOptionItems;
}
class OptionItem {
final String id;
final String title;
OptionItem({@required this.id, @required this.title});
}
Run Code Online (Sandbox Code Playgroud)
接下来,创建文件file select_drop_list.dart:
import 'package:flutter/material.dart';
import 'package:time_keeping/model/drop_list_model.dart';
import 'package:time_keeping/widgets/src/core_internal.dart';
class SelectDropList extends StatefulWidget {
final OptionItem itemSelected;
final DropListModel dropListModel;
final Function(OptionItem optionItem) onOptionSelected;
SelectDropList(this.itemSelected, this.dropListModel, this.onOptionSelected);
@override
_SelectDropListState createState() => _SelectDropListState(itemSelected, dropListModel);
}
class _SelectDropListState extends State<SelectDropList> with SingleTickerProviderStateMixin {
OptionItem optionItemSelected;
final DropListModel dropListModel;
AnimationController expandController;
Animation<double> animation;
bool isShow = false;
_SelectDropListState(this.optionItemSelected, this.dropListModel);
@override
void initState() {
super.initState();
expandController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 350)
);
animation = CurvedAnimation(
parent: expandController,
curve: Curves.fastOutSlowIn,
);
_runExpandCheck();
}
void _runExpandCheck() {
if(isShow) {
expandController.forward();
} else {
expandController.reverse();
}
}
@override
void dispose() {
expandController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 17),
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white,
boxShadow: [
BoxShadow(
blurRadius: 10,
color: Colors.black26,
offset: Offset(0, 2))
],
),
child: new Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(Icons.card_travel, color: Color(0xFF307DF1),),
SizedBox(width: 10,),
Expanded(
child: GestureDetector(
onTap: () {
this.isShow = !this.isShow;
_runExpandCheck();
setState(() {
});
},
child: Text(optionItemSelected.title, style: TextStyle(
color: Color(0xFF307DF1),
fontSize: 16),),
)
),
Align(
alignment: Alignment(1, 0),
child: Icon(
isShow ? Icons.arrow_drop_down : Icons.arrow_right,
color: Color(0xFF307DF1),
size: 15,
),
),
],
),
),
SizeTransition(
axisAlignment: 1.0,
sizeFactor: animation,
child: Container(
margin: const EdgeInsets.only(bottom: 10),
padding: const EdgeInsets.only(bottom: 10),
decoration: new BoxDecoration(
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)),
color: Colors.white,
boxShadow: [
BoxShadow(
blurRadius: 4,
color: Colors.black26,
offset: Offset(0, 4))
],
),
child: _buildDropListOptions(dropListModel.listOptionItems, context)
)
),
// Divider(color: Colors.grey.shade300, height: 1,)
],
),
);
}
Column _buildDropListOptions(List<OptionItem> items, BuildContext context) {
return Column(
children: items.map((item) => _buildSubMenu(item, context)).toList(),
);
}
Widget _buildSubMenu(OptionItem item, BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 26.0, top: 5, bottom: 5),
child: GestureDetector(
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
padding: const EdgeInsets.only(top: 20),
decoration: BoxDecoration(
border: Border(top: BorderSide(color: Colors.grey[200], width: 1)),
),
child: Text(item.title,
style: TextStyle(
color: Color(0xFF307DF1),
fontWeight: FontWeight.w400,
fontSize: 14),
maxLines: 3,
textAlign: TextAlign.start,
overflow: TextOverflow.ellipsis),
),
),
],
),
onTap: () {
this.optionItemSelected = item;
isShow = false;
expandController.reverse();
widget.onOptionSelected(item);
},
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
初始化值:
DropListModel dropListModel = DropListModel([OptionItem(id: "1", title: "Option 1"), OptionItem(id: "2", title: "Option 2")]);
OptionItem optionItemSelected = OptionItem(id: null, title: "Ch?n quy?n truy c?p");
Run Code Online (Sandbox Code Playgroud)
最后使用它:
SelectDropList(
this.optionItemSelected,
this.dropListModel,
(optionItem){
optionItemSelected = optionItem;
setState(() {
});
},
)
Run Code Online (Sandbox Code Playgroud)
ceg*_*gas 14
对于解决方案,滚动到答案的末尾。
首先,让我们研究一下错误的含义(我引用了Flutter 1.2引发的错误,但是想法是相同的):
断言失败:行560位置15:'item == null || items.isEmpty || 值== null || items.where(((DropdownMenuItem item)=> item.value == value).length == 1':不正确。
有四个or条件。必须至少满足其中之一:
DropdownMenuItem小部件列表)。这样就消除了items == null。items.isEmpty。_selectedLocation还给出了值()。这样就消除了value == null。请注意,这是DropdownButton的值,而不是DropdownMenuItem的值。因此,仅保留最后的检查。归结为:
遍历
DropdownMenuItem。找到所有value等于的_selectedLocation。然后,检查找到多少与之匹配的项目。必须只有一个具有此值的小部件。否则,抛出错误。
呈现代码的方式,没有DropdownMenuItem值的窗口小部件_selectedLocation。相反,所有小部件的值都设置为null。由于null != _selectedLocation,最后一个条件失败。通过设置_selectedLocation为null- 验证该应用程序应运行。
要解决此问题,我们首先需要为每个设置一个值DropdownMenuItem(以便可以将某些内容传递给onChanged回调):
return DropdownMenuItem(
child: new Text(location),
value: location,
);
Run Code Online (Sandbox Code Playgroud)
该应用程序仍将失败。这是因为您的列表仍然不包含_selectedLocation的值。您可以通过两种方式使应用程序工作:
items.where((DropdownMenuItem<T> item) => item.value == value).length == 1)的小部件。如果要让用户重新选择Please choose a location选项,可能会很有用。hint:paremter并设置selectedLocation为null(满足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(),
),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
Sed*_*ush 11
对于任何有兴趣实施DropDown自定义的人,class您可以按照以下步骤操作。
假设您有一个Language使用以下代码调用的类和一个static返回List<Language>
class Language {
final int id;
final String name;
final String languageCode;
const Language(this.id, this.name, this.languageCode);
}
const List<Language> getLanguages = <Language>[
Language(1, 'English', 'en'),
Language(2, '?????', 'fa'),
Language(3, '????', 'ps'),
];
Run Code Online (Sandbox Code Playgroud)
任何你想要实现DropDown,你可以import在Language类的第一次使用它作为后续
DropdownButton(
underline: SizedBox(),
icon: Icon(
Icons.language,
color: Colors.white,
),
items: getLanguages.map((Language lang) {
return new DropdownMenuItem<String>(
value: lang.languageCode,
child: new Text(lang.name),
);
}).toList(),
onChanged: (val) {
print(val);
},
)
Run Code Online (Sandbox Code Playgroud)
您必须考虑到这一点(来自DropdownButton文档):
“项目必须具有不同的值,如果value不为null,则必须在其中。”
所以基本上你有这个字符串列表
List<String> _locations = ['A', 'B', 'C', 'D'];
Run Code Online (Sandbox Code Playgroud)
并且您在Dropdown value属性中的值是这样初始化的:
String _selectedLocation = 'Please choose a location';
Run Code Online (Sandbox Code Playgroud)
只需尝试以下列表:
List<String> _locations = ['Please choose a location', 'A', 'B', 'C', 'D'];
Run Code Online (Sandbox Code Playgroud)
那应该工作:)
如果不想添加这样的String(不在列表上下文中),也请签出“提示”属性,可以使用如下所示的内容:
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(() {});
});
Run Code Online (Sandbox Code Playgroud)
小智 7
将值放在 items.then 中,它将起作用,
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(() {});
})
Run Code Online (Sandbox Code Playgroud)
您需要添加value: location代码才能使用它。检查这个出来。
items: _locations.map((String location) {
return new DropdownMenuItem<String>(
child: new Text(location),
value: location,
);
}).toList(),
Run Code Online (Sandbox Code Playgroud)
您可以使用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(),
),
),
);
...
...
Run Code Online (Sandbox Code Playgroud)
请参考这个颤振网页