1、定义模型数组,储存搜索数据
//搜索得到的数组
List<String> models = [];
//所有联系人数据
List<String> allModels = [
'刘备',
'孙权',
"诸葛亮",
"赵云",
"周瑜",
"鲁肃",
"司马懿",
"袁绍",
"华佗",
"华雄",
"公孙瓒",
"刘表",
"典韦",
"黄忠",
"刘禅",
"徐庶",
"郭嘉",
"荀攸",
'曹操',
];
2、模型数组添加数据
//输入的字符
String words = '';
//搜索展示的内容
void searcherData(String text) {
models.clear();
words=text;
if (text.isNotEmpty) {
for (int i = 0; i < allModels.length; i++) {
String name = allModels[i];
if (name.contains(text)) {
models.add(name);
}
}
}
setState(() {});
}
使用contains函数,获取所有含有输出值text的姓名
3、拼接模型数据,实现高亮
//文本颜色
final TextStyle _normalStyle = const TextStyle(
fontSize: 16,
color: Colors.black,
);
final TextStyle _heighlightStyle = const TextStyle(
fontSize: 16,
color: Colors.green,
);
Widget _title(String name){
List<TextSpan> spans = [];
List<String> strs = name.split(widget.words);
for(int i = 0;i<strs.length;i++){
String str = strs[i];
if(str == '' && i<strs.length-1){
spans.add(TextSpan(text:widget.words,style: _heighlightStyle));
} else {
spans.add(TextSpan(text: str, style: _normalStyle));
if(i<strs.length-1){
spans.add(TextSpan(text:widget.words,style: _heighlightStyle));
}
}
}
return RichText(text: TextSpan(children: spans));
}
将输入值进行高亮,利用split实现。逻辑:每分割一个字符,必定会含有一个输入值,所有每次都会在其他分割字符后加上高亮输入值(最后一个分割字符除外);如果是一开始就被分割,第一个字符就是空,则直接添加高亮输入值。
效果展示:
完整代码:
//searcher_people.dart
import 'package:flutter/material.dart';
import '../XKTabBar.dart';
import '../other/line.dart';
class SearcherPeople extends StatefulWidget {
final String titlesList;
final String words;
const SearcherPeople(this.titlesList, this.words, {Key? key}) : super(key: key);
@override
State<SearcherPeople> createState() => _ContactPeopleState();
}
class _ContactPeopleState extends State<SearcherPeople> {
//文本颜色
final TextStyle _normalStyle = const TextStyle(
fontSize: 16,
color: Colors.black,
);
final TextStyle _heighlightStyle = const TextStyle(
fontSize: 16,
color: Colors.green,
);
Widget _title(String name){
List<TextSpan> spans = [];
List<String> strs = name.split(widget.words);
for(int i = 0;i<strs.length;i++){
String str = strs[i];
if(str == '' && i<strs.length-1){
spans.add(TextSpan(text:widget.words,style: _heighlightStyle));
} else {
spans.add(TextSpan(text: str, style: _normalStyle));
if(i<strs.length-1){
spans.add(TextSpan(text:widget.words,style: _heighlightStyle));
}
}
}
return RichText(text: TextSpan(children: spans));
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
height: 50.0,
color: Colors.white,
child: ListTile(
title: _title(widget.titlesList),
leading: Image.asset(
"images/${widget.titlesList}.png",
width: 35.0,
height: 35.0,
fit: BoxFit.cover,
),
),
),
const line(),
],
);
}
}
//search_page.dart
import 'package:flutter/material.dart';
import 'package:weixin/widget/searcher_people.dart';
import 'Home.dart';
class SearcherBar extends StatefulWidget {
const SearcherBar({super.key});
@override
State<SearcherBar> createState() => _SearcherBarState();
}
class _SearcherBarState extends State<SearcherBar> {
final TextEditingController _controller = TextEditingController();
//搜索得到的数组
List<String> models = [];
//所有联系人数据
List<String> allModels = [
'刘备',
'孙权',
"诸葛亮",
"赵云",
"周瑜",
"鲁肃",
"司马懿",
"袁绍",
"华佗",
"华雄",
"公孙瓒",
"刘表",
"典韦",
"黄忠",
"刘禅",
"徐庶",
"郭嘉",
"荀攸",
'曹操',
];
//输入的字符
String words = '';
//搜索展示的内容
void searcherData(String text) {
models.clear();
words=text;
if (text.isNotEmpty) {
for (int i = 0; i < allModels.length; i++) {
String name = allModels[i];
if (name.contains(text)) {
models.add(name);
}
}
}
setState(() {});
}
//控制取消符号是否显示
bool _showClear = false;
void _onChanged(String text) {
searcherData(text);
setState(() {
_showClear = text.isNotEmpty;
});
// if (text.isNotEmpty) {
// setState(() {
// _showClear = true;
// });
// } else {
// setState(() {
// _showClear = false;
// });
// }
}
double screenWith(BuildContext context) {
return MediaQuery.of(context).size.width;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: 900.0,
color: Colors.grey[200],
child: Column(
children: [
const SizedBox(
height: 40.0,
),
//搜索框
Container(
height: 44.0,
color: Colors.grey[200],
child: Row(
children: [
Container(
width: screenWith(context) - 40,
height: 34.0,
margin: const EdgeInsets.only(left: 5, right: 5),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(6.0),
),
child: Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
// 右边留有一些空间
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Image(
image:
AssetImage('images/Fav_Search_Icon@3x.png'),
width: 20,
),
Expanded(
flex: 1,
child: TextField(
controller: _controller,
onChanged: _onChanged,
cursorColor: Colors.green,
style: const TextStyle(
fontSize: 18.0,
color: Colors.black,
fontWeight: FontWeight.w300,
),
decoration: const InputDecoration(
contentPadding: EdgeInsets.only(
left: 5.0, right: 5.0, bottom: 10.0),
border: InputBorder.none,
hintText: '搜索'),
),
),
_showClear
? GestureDetector(
onTap: () {
setState(() {
_controller.clear();
_onChanged('');
});
},
child: const Icon(Icons.cancel,
color: Colors.grey),
)
: Container(),
],
),
)),
GestureDetector(
onTap: () {
//返回首页
Navigator.pop(context);
},
child: const Text('取消'),
),
],
),
),
Expanded(
child: ListView.builder(
itemCount: models.length,
itemBuilder: (BuildContext context, int index) {
return SearcherPeople(models[index],words);
}))
],
),
),
);
}
}