Flutter 将搜索数据传递给 SearchDelegate
Posted
技术标签:
【中文标题】Flutter 将搜索数据传递给 SearchDelegate【英文标题】:Flutter pass search data to SearchDelegate 【发布时间】:2019-12-12 12:46:23 【问题描述】:我创建了带有标签的产品,所以当用户按下标签按钮时,它将打开 SearchDelegate 并搜索该标签,
那么如何将标签名称传递给搜索代理查询?
我的代码:
class DataSearch extends SearchDelegate<Product>
final suggestions = new ProductsRepository().fetchAllProducts();
final lastOnes = ['suggest'];
@override
List<Widget> buildActions(BuildContext context)
return [
IconButton(icon: Icon(Icons.clear), onPressed: ()
query = '';
showSuggestions(context);
),
];
@override
Widget buildLeading(BuildContext context)
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: ()
close(context, null);
);
@override
Widget buildResults(BuildContext context)
final suggestionList = query.isEmpty
? []
: suggestions.where((p) => p.title.contains(query)).toList();
double _gridSize =
MediaQuery.of(context).size.height * 0.58; //88% of screen
double childAspectRatio = MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.0);
return Column(children: <Widget>[
new Container(
height: _gridSize + 100,
decoration: BoxDecoration(
color: const Color(0xFFeeeeee),),
padding: EdgeInsets.only(left: 10, right: 10),
child: new Column(children: <Widget>[
new Container(
margin: EdgeInsets.only(top: 40),
child: new Column(children: <Widget>[
new Container(
height: _gridSize - 60,
margin: EdgeInsets.only(top: 0),
child: new PhysicalModel(
color: Colors.transparent,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(_gridSize / 10 - 10),
bottomRight:
Radius.circular(_gridSize / 10 - 10)),
clipBehavior: Clip.antiAlias,
child: GridView.builder(
itemCount: suggestionList.length,
gridDelegate:
new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: childAspectRatio),
itemBuilder: (BuildContext context, int index)
return new Padding(
padding: EdgeInsets.only(
top: index % 2 == 0 ? 20 : 0,
right: index % 2 == 0 ? 5 : 0,
left: index % 2 == 1 ? 5 : 0,
bottom: index % 2 == 1 ? 20 : 0),
child:
ProductWidget(
product: suggestionList[index]));
)
)),
]))
])),
// new MinimalCart(_gridSize)
]);
@override
Widget buildSuggestions(BuildContext context)
final suggestionList = query.isEmpty
? []
: suggestions.where((p) => p.title.contains(query)).toList();
return ListView.builder(
itemBuilder: (context, index) =>
ListTile(
leading: Icon(Icons.add),
onTap: () => showResults(context),
title: RichText(
text: TextSpan(
text: suggestionList[index].title.substring(
0, query.length),
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.bold),
children: [
TextSpan(
text: suggestionList[index].title.substring(
query.length),
style: TextStyle(
color: Colors.grey))
])),
),
itemCount: suggestionList.length,
);
我的标签按钮:
child: FlatButton(
child: Text(widget.product.tags[index]),
onPressed: ()
showSearch(
context: context,
delegate: DataSearch(),
);
)
我尝试传递 query 变量,但它不起作用,因为 query 在小部件内,有其他方法吗?
【问题讨论】:
【参考方案1】:您可以使用参数q
作为String 和final 的DataSearch
的构造函数。然后将this.q
设置为您想要的查询。并在按钮中初始化DataSearch
,并将产品标签作为参数。
试试这个代码,告诉我它是否有效。
class DataSearch extends SearchDelegate<Product>
final suggestions = new ProductsRepository().fetchAllProducts();
final lastOnes = ['suggest'];
final String q;
DataSearch(this.q)
query = this.q;
@override
List<Widget> buildActions(BuildContext context)
return [
IconButton(icon: Icon(Icons.clear), onPressed: ()
query = '';
showSuggestions(context);
),
];
@override
Widget buildLeading(BuildContext context)
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: ()
close(context, null);
);
@override
Widget buildResults(BuildContext context)
final suggestionList = query.isEmpty
? []
: suggestions.where((p) => p.title.contains(query)).toList();
double _gridSize =
MediaQuery.of(context).size.height * 0.58; //88% of screen
double childAspectRatio = MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.0);
return Column(children: <Widget>[
new Container(
height: _gridSize + 100,
decoration: BoxDecoration(
color: const Color(0xFFeeeeee),),
padding: EdgeInsets.only(left: 10, right: 10),
child: new Column(children: <Widget>[
new Container(
margin: EdgeInsets.only(top: 40),
child: new Column(children: <Widget>[
new Container(
height: _gridSize - 60,
margin: EdgeInsets.only(top: 0),
child: new PhysicalModel(
color: Colors.transparent,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(_gridSize / 10 - 10),
bottomRight:
Radius.circular(_gridSize / 10 - 10)),
clipBehavior: Clip.antiAlias,
child: GridView.builder(
itemCount: suggestionList.length,
gridDelegate:
new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: childAspectRatio),
itemBuilder: (BuildContext context, int index)
return new Padding(
padding: EdgeInsets.only(
top: index % 2 == 0 ? 20 : 0,
right: index % 2 == 0 ? 5 : 0,
left: index % 2 == 1 ? 5 : 0,
bottom: index % 2 == 1 ? 20 : 0),
child:
ProductWidget(
product: suggestionList[index]));
)
)),
]))
])),
// new MinimalCart(_gridSize)
]);
@override
Widget buildSuggestions(BuildContext context)
final suggestionList = query.isEmpty
? []
: suggestions.where((p) => p.title.contains(query)).toList();
return ListView.builder(
itemBuilder: (context, index) =>
ListTile(
leading: Icon(Icons.add),
onTap: () => showResults(context),
title: RichText(
text: TextSpan(
text: suggestionList[index].title.substring(
0, query.length),
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.bold),
children: [
TextSpan(
text: suggestionList[index].title.substring(
query.length),
style: TextStyle(
color: Colors.grey))
])),
),
itemCount: suggestionList.length,
);
还有你的按钮
child: FlatButton(
child: Text(widget.product.tags[index]),
onPressed: ()
showSearch(
context: context,
delegate: DataSearch(widget.product.tags[index]),
);
)
【讨论】:
idk 为什么我无法弄清楚这一点,感谢@Shady Boshra。这对我有用以上是关于Flutter 将搜索数据传递给 SearchDelegate的主要内容,如果未能解决你的问题,请参考以下文章
在 Flutter 中,如何将数据传递给 Stateless Widget?
Flutter(Web)如何监听javascript事件或将javascript数据传递给flutter?
将 StatefulWidget 数据传递给 State 类而不使用构造函数