flutter_weixin搜索高亮功能实现

 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);

                    }))

          ],

        ),

      ),

    );

  }

}


评论

此博客中的热门博文

登录界面实现

flutter_weixin索引条实现