如何在Flutter DropDown按钮中搜索



我在本地json中有一个国家名称列表。我可以加载本地json并分配给DropDown按钮。json文件中有一个193个国家,如下所示。如果我想选择美国,用户必须一直向下滚动。如何输入国家名称,如;如果我用户输入U或U,下拉列表可以快速过滤并列出所有以U开头的国家,如美国如何在Flutter DropDownbutton项目中搜索

{
"country": [
{
"countryCode": "AD",
"countryName": "Andorra",
"currencyCode": "EUR",
"isoNumeric": "020"
},
{
"countryCode": "AE",
"countryName": "United Arab Emirates",
"currencyCode": "AED",
"isoNumeric": "784"
},
{
"countryCode": "AF",
"countryName": "Afghanistan",
"currencyCode": "AFN",
"isoNumeric": "004"
},
//...
]
}

您可以使用searchable_dropdown包:https://pub.dev/packages/searchable_dropdown

这是我的示例代码searchable_dropdown不适用于类列表

如果你使用像我的例子那样的类列表,请确保你放了以下内容

@override
String toString() {
return this.key;
}

一种方法是使用TextEditingController来过滤ListView,如下所示:

class YourPage extends StatefulWidget {
@override
State createState() => YourPageState();
}
class YourPageState extends State<YourPage> {
List<Country> countries = new List<Country>();
TextEditingController controller = new TextEditingController();
String filter;
@override
void initState() {
super.initState();
//fill countries with objects
controller.addListener(() {
setState(() {
filter = controller.text;
});
});
}
@override
void dispose() {
super.dispose();
controller.dispose();
}
@override
Widget build(BuildContext context) {
return new Material(
color: Colors.transparent,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Padding(
padding: new EdgeInsets.only(top: 8.0, left: 16.0, right: 16.0),
child: new TextField(
style: new TextStyle(fontSize: 18.0, color: Colors.black),
decoration: InputDecoration(
prefixIcon: new Icon(Icons.search),
suffixIcon: new IconButton(
icon: new Icon(Icons.close),
onPressed: () {
controller.clear();
FocusScope.of(context).requestFocus(new FocusNode());
},
),
hintText: "Search...",
),
controller: controller,
)),
new Expanded(
child: new Padding(
padding: new EdgeInsets.only(top: 8.0),
child: _buildListView()),
)
],
));
}
Widget _buildListView() {
return ListView.builder(
itemCount: countries.length,
itemBuilder: (BuildContext context, int index) {
if (filter == null || filter == "") {
return _buildRow(countries[index]);
} else {
if (countries[index].countryName
.toLowerCase()
.contains(filter.toLowerCase())) {
return _buildRow(countries[index]);
} else {
return new Container();
}
}
});
}
Widget _buildRow(Country c) {
return new ListTile(
title: new Text(
c.countryName,
),
subtitle: new Text(
c.countryCode,
));
}
}

您可以使用dropdown_search包,如下所示。

import 'package:dropdown_search/dropdown_search.dart';
DropdownSearch<String>(
popupProps: PopupProps.menu(
showSearchBox: true,
showSelectedItems: true,
disabledItemFn: (String s) => s.startsWith('I'),
),
items: ["Brazil", "Italia (Disabled)", "Tunisia", 'Canada'],
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
labelText: "Menu mode",
hintText: "country in menu mode",
),
),
onChanged: print,
selectedItem: "Brazil",
)

确保已在popupProps下设置了showSearchBox属性。文档中尚未提及此属性。有关更多属性,请参见PopupProps源代码。

使用textfield_search:^0.8.0插件视图示例

TextFieldSearch(
decoration: InputDecoration(
hintText: "Search",
prefixIcon: Icon(
Icons.search,
color: Colors.black45,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Colors.grey[200],
),
initialList: constants.VEHICLELIST,
label: "label",
controller: selectedVehicle),

我认为这有点过时了,因为现在只使用附带的材料包并使用DropDownMenu小部件就可以了。您可以使用enableFilter: True属性来启用手动搜索。如果您以某种方式单击小部件,但它不允许您键入搜索,则添加属性requestFocusOnTap: true会有所帮助,尤其是在ListViews/ListTiles/滚动卡

DropdownMenu<CountryEntity>(
controller: countryController,
label: const Text('Country'),
width: 300,
dropdownMenuEntries: countryEntities,
enableFilter: true,
menuStyle: const MenuStyle(
alignment: Alignment.bottomLeft,
maximumSize:
MaterialStatePropertyAll(Size.fromHeight(Sizes.p124)),),
requestFocusOnTap: true,
onSelected: (country) {
setState(() {
selectedCountryId = country;
});
},
);

最新更新