Flutter 自带的搜索组件

效果如下



官方需要重写四个关键方法

class searchBarDelegate extends SearchDelegate<String> {
/*这个方法返回一个控件列表,显示为搜索框右边的图标按钮,这里设置为一个清除按钮,并且在搜索内容为空的时候显示建议搜索内容,使用的是showSuggestions(context)方法:*/
@override
List<Widget> buildActions(BuildContext context) {
return null;
}
/*这个方法返回一个控件,显示为搜索框左侧的按钮,一般设置为返回,这里返回一个具有动态效果的返回按钮:*/
@override
Widget buildLeading(BuildContext context) {
return null;
}
@override
Widget buildResults(BuildContext context) {
return null;
}
/*这个方法返回一个控件,显示为搜索内容区域的建议内容。*/
@override
Widget buildSuggestions(BuildContext context) {
return null;
}
/*这个方法返回一个主题,也就是可以自定义搜索界面的主题样式:*/
@override
ThemeData appBarTheme(BuildContext context) {
// TODO: implement appBarTheme
return super.appBarTheme(context);
}
}

首页展示检索框

Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Padding(
padding: const EdgeInsets.only(top: 2, bottom: 2, left: 16),
child: Container(
height: 35,
width: MediaQuery.of(context).size.width - 64,
decoration: BoxDecoration(
color: const Color.fromRGBO(230, 230, 230, 1.0),
borderRadius: BorderRadius.circular(20)),
child: InkWell(
child: const Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 10, right: 10),
child: Icon(Icons.search, color: Colors.grey)),
Text(
"输入关键词查找片源",
style: TextStyle(color: Colors.grey, fontSize: 15),
)
],
),
onTap: () {
showSearch(context: context, delegate: SearchBarDelegate());
},
),
),
),
toolbarHeight: 45.sp,
bottom: TabBar(
controller: _tabController,
tabs: tabs.map((e) => Tab(text: e)).toList(),
),
),

实现 SearchDelegate

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class SearchBarDelegate extends SearchDelegate<String> {
var nameList = ["完美世界", "西行记", "仙逆", "遮天", "圣墟", "斗罗大陆", "涉谷愤怒的海"];
late bool flag;
@override
String get searchFieldLabel => '输入关键词查找片源';
@override
TextStyle get searchFieldStyle => TextStyle(fontSize: 14.0.sp);
@override
List<Widget>? buildActions(BuildContext context) {
return [
IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
query = "";
showSuggestions(context);
},
)
];
}
@override
Widget? buildLeading(BuildContext context) {
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow, progress: transitionAnimation),
onPressed: () {
if (query.isEmpty) {
close(context, '');
} else {
query = "";
showSuggestions(context);
}
},
);
}
@override
Widget buildResults(BuildContext context) {
for (int i = 0; i < nameList.length; i++) {
if (query == nameList[i]) {
flag = true;
break;
} else {
flag = false;
}
}
return flag == true
? Padding(
padding: const EdgeInsets.all(16),
child: InkWell(
child: Text(query),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TextScreen(s: query),
),
);
},
))
: const Center(
child: Text("很抱歉,没有找到该搜索结果"),
);
}
@override
Widget buildSuggestions(BuildContext context) {
final suggestionsList = query.isEmpty
? nameList
: nameList.where((input) => input.startsWith(query)).toList();
return ListView.builder(
itemCount: suggestionsList.length,
itemBuilder: (context, index) {
return InkWell(
child: ListTile(
title: RichText(
text: TextSpan(
text: suggestionsList[index].substring(0, query.length),
style: const TextStyle(
color: Colors.black, fontWeight: FontWeight.bold),
children: [
TextSpan(
text: suggestionsList[index].substring(query.length),
style: const TextStyle(color: Colors.grey))
]),
),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TextScreen(s: suggestionsList[index]),
),
);
},
);
});
}
}
class TextScreen extends StatelessWidget {
final String s;
const TextScreen({super.key, required this.s});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("搜索结果内容"),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Center(
child: Text(s),
)),
);
}
}

为了和首页保持一样的效果需要修改源码

  • 修改文字和大小 提供重写方法
@override
String get searchFieldLabel => '输入关键词查找片源';
@override
TextStyle get searchFieldStyle => TextStyle(fontSize: 14.0.sp);
  • 要在输入框之前加一个 检索的图标
  • ~/flutter/packages/flutter/lib/src/material/search.dart
// 导入icon
import 'package:flutter/material.dart';
// 修改源码 直接到文件末尾
return Semantics(
explicitChildNodes: true,
scopesRoute: true,
namesRoute: true,
label: routeName,
child: Theme(
data: theme,
child: Scaffold(
appBar: AppBar(
leading: widget.delegate.buildLeading(context),
title: TextField(
controller: widget.delegate._queryTextController,
focusNode: focusNode,
style: widget.delegate.searchFieldStyle ?? theme.textTheme.titleLarge,
textInputAction: widget.delegate.textInputAction,
keyboardType: widget.delegate.keyboardType,
onSubmitted: (String _) => widget.delegate.showResults(context),
decoration: InputDecoration(
// 加这个位置
prefixIcon: Icon(Icons.search, color: Colors.grey),
hintText: searchFieldLabel
),
),
flexibleSpace: widget.delegate.buildFlexibleSpace(context),
actions: widget.delegate.buildActions(context),
bottom: widget.delegate.buildBottom(context),
),
body: AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
child: body,
),
),
),
);
posted @   vx_guanchaoguo0  阅读(810)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 本地部署 DeepSeek:小白也能轻松搞定!
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 从 Windows Forms 到微服务的经验教训
· 李飞飞的50美金比肩DeepSeek把CEO忽悠瘸了,倒霉的却是程序员
· 超详细,DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方Dee
点击右上角即可分享
微信分享提示