「这是我参与11月更文应战的第24天,活动详情检查:2021最终一次更文应战」。
- 上一篇咱们完成了自界说查找框,咱们完成查找框的内容完成搜素的作用
1. 页面传值
咱们要查找主页数据,所以咱们跳转的时分需要把值传递
过来。
界说数据,和初始化的方法,选择可选的
class SearchPage extends StatefulWidget {
final List<ChatModel>? listData;
SearchPage({this.listData});
@override
_SearchPageState createState() => _SearchPageState();
}
咱们点击searchCell
的时分传入,这样咱们searchPage
就拿到数据了
return GestureDetector(
onTap: (){
Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => SearchPage(listData: _listData,)));
print('点击了');
},
2. 完成查找
咱们是把searchBar
抽出来放到了一个单独的类,咱们能够把数据传进去,依据查找的内容匹配查找的成果在在searchPage
展现,也能够把searcheBar
的值告诉当时页面,之后进行查找成果展现
2.1 searchBar查找
class SearchBar extends StatefulWidget {
final List<ChatModel>? listData;
final ValueChanged<List<ChatModel>>? searchResult;
SearchBar({this.listData,this.searchResult});
@override
_SearchBarState createState() => _SearchBarState();
}
咱们界说一个ValueChanged
,当产生改动的时分就回调,咱们完成这个查找的方法
//查找
searchResult(String searchText){
if (searchText.isNotEmpty && widget.listData!.isNotEmpty) {
searResults.clear();
print('statr');
print(searchText);
print(widget.listData!.length);
for( int i =0;i<widget.listData!.length;i++){
String name = widget.listData![i].name!;
if(name.contains(searchText)){
searResults.add(widget.listData![i]);
}
}
print(searResults);
widget.searchResult!(searResults);//回来
}
}
咱们在查找框的值产生改动的使用调用
_onChanged(String text){
searchResult(text);
setState(() {
isShowCancleIcon = text.length>0;//当输入框内容大于0的时分显现铲除按钮
});
}
咱们界说时分监听回调,当产生改动的时分咱们就setState
的方法赋值刷新页面
cell咱们之前主页的款式
2.2 searchPage完成查找
咱们界说查找框的回调,把查找框的查找内容传递出去
final ValueChanged<String>? onChanged;
SearchBar({this.onChanged});
传递出去
if(widget.onChanged != null){
widget.onChanged!(text);
}
在page页接收
SearchBar(listData: widget.listData,
searchResult:(List<ChatModel> list){
// print(list);
// setState(() {
// searResults =list;
// });
},
onChanged: (String str){
_searchData(str);
},
),
承受的数据进行处理
List<ChatModel> _modals = [];
void _searchData(String text) {
_modals.clear(); //每次查找先清空!
if (text.length > 0) {
for (int i = 0; i < widget.listData!.length; i++) {
//循环检索
String name = widget.listData![i].name!;
if (name.contains(text)) {
_modals.add(widget.listData![i]);
}
}
}
setState(() {});
}
成果
3. 显现选中字体
想要完成咱们输入的字显现选中
的色彩,咱们要自界说标题使用富文本
展现
这儿咱们修改下接口改为英文名字
咱们依据这个传入的字符串截取split
Widget _titleName(String name){
List<TextSpan> spans = [];
List<String> strs = name.split(_searchStr);
print('$name:$strs');
return RichText(text: TextSpan(children: spans));
}
打印成果
字符串依据咱们选中的进行分割
,其中数组中空字符串
代表了咱们输入的搜素内容
,咱们能够依据这个判别
可是仍是有些问题,比如咱们搜素ss
,打印成果
Jessica Rodriguez:[Je, ica Rodriguez],
咱们判别数组下标不是最终一个
的话,每次添加他们之间的距离
,因为字符串时以这个查找内容区分的,没在数组中展现
,可是有距离
就表明咱们之间有输入内容
。
咱们判别当时i不是最终一个
就加入咱们的查找内容
咱们还有一个问题,当最终一个是咱们检索的内容的话,它是‘’
可是咱们在他前面又添加了
,有问题会。
因此咱们在判别空字符串的时分还要加个判别,空字符串不是最终一个
。
最终代码咱们替换之前的Text
Widget _titleName(String name){
TextStyle _normalStyle =const TextStyle(
color: Colors.black,
fontSize: 16
);
TextStyle _selectStyle = const TextStyle(
color: Colors.green,
fontSize: 16
);
List<TextSpan> spans = [];
List<String> strs = name.split(_searchStr);
print('$name:$strs');
for(int i =0 ;i<strs.length;i++){
String indexStr = strs[i];
if(indexStr == ''&& i < strs.length - 1){
spans.add(TextSpan(text: _searchStr,style: _selectStyle));
}else{
spans.add(TextSpan(text: indexStr,style: _normalStyle));
if(i< strs.length -1){
spans.add(TextSpan(text: _searchStr,style: _selectStyle));
}
}
}
return RichText(text: TextSpan(children: spans));
}
后面会上传下这个demo到github 感兴趣的能够看看。