Flutter:按字符搜索列表

Posted

技术标签:

【中文标题】Flutter:按字符搜索列表【英文标题】:Flutter: search lists char by char 【发布时间】:2020-04-10 15:41:23 【问题描述】:

我在“Flutter: Searching Through List”中看到了非常好的代码。但是,我有一个列表,我希望从列表项的开头逐个字符地比较用户输入,而不是如果输入包含在列表项中的某个位置。 IE。如果用户输入“abc”,则应仅将其与列表项的前 3 个字符进行比较。有人可以帮忙修改代码吗?

【问题讨论】:

【参考方案1】:

以下代码将为您提供以您提供的字符串开头的搜索结果:

List<String> searchResults = yourList.where((String item)=>item.startsWith('your_search_characters')).toList();

可以尝试验证您的输出的演示:

void main() 
  List<String> yourList = <String>[
    'abcd', 'cabcd','dcabcd', 'abcdefg'
  ];

  List<String> searchResults = yourList.where((String item)=>item.startsWith('ab')).toList();

  print(searchResults);

已编辑: 您可以在 _ListPersonPageState> build()

中使用整个代码

替换:

if(_filteredList[i].personFirstName.toLowerCase().contains(filter.toLowerCase())) 

与:

if(_filteredList[i].personFirstName.toLowerCase().startsWith(filter.toLowerCase())) 

以下是完整的工作代码供您参考:

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';

void main() => runApp(new AdvancedSearch());

class AdvancedSearch extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return new MaterialApp(
      title: 'List of People',
      home: new ListPersonPage(title: 'List of People'),
    );
  


class ListPersonPage extends StatefulWidget 
  ListPersonPage(Key key, this.title) : super(key: key);

  final String title;

  @override
  _ListPersonPageState createState() => _ListPersonPageState();


class _ListPersonPageState extends State<ListPersonPage> 
  List<Person> _personList = [];
  List<Person> _filteredList = [];
  TextEditingController controller = new TextEditingController();
  String filter = "";

  Widget appBarTitle = new Text("List of People");
  Icon actionIcon = new Icon(Icons.search);

  @override
  void dispose() 
    controller.dispose();
    super.dispose();
  

  @override
  void initState() 
    PersonDataBuilder pdb = new PersonDataBuilder();
    List<Person> tmpList = new List<Person>();
    for(int i=0; i < pdb.getPeople().length; i++) 
      tmpList.add(pdb.getPeople()[i]);
    
    setState(() 
      _personList = tmpList;
      _filteredList = _personList;
    );
    controller.addListener(() 
      if(controller.text.isEmpty) 
        setState(() 
          filter = "";
          _filteredList = _personList;
        );
       else 
        setState(() 
          filter = controller.text;
        );
      
    );
    super.initState();
  

  @override
  Widget build(BuildContext context) 

    final appTopAppBar = AppBar(
      elevation: 0.1,
      title: appBarTitle,
      actions: <Widget>[
        new IconButton(
          icon: actionIcon,
          onPressed: () 
            setState(() 
              if (this.actionIcon.icon == Icons.search) 
                this.actionIcon = new Icon(Icons.close);
                this.appBarTitle = new TextField(
                  controller: controller,
                  decoration: new InputDecoration(
                    prefixIcon: new Icon(Icons.search, color: Colors.white),
                    hintText: "Search...",
                    hintStyle: new TextStyle(color: Colors.white),
                  ),
                  style: new TextStyle(
                    color: Colors.white,
                  ),
                  autofocus: true,
                  cursorColor: Colors.white,
                );
               else 
                this.actionIcon = new Icon(Icons.search);
                this.appBarTitle = new Text("List of People");
                _filteredList = _personList;
                controller.clear();
              
            );
          ,
        ),
      ],
    );

    ListTile personListTile(Person person) => ListTile(
      title: Text(
        person.personFirstName + " " + person.personLastName,
        style: TextStyle(color: Colors.black45, fontWeight: FontWeight.bold),
      ),);

    Card personCard(Person person) => Card(
      child: Container(
        decoration: BoxDecoration(color: Colors.grey[300]),
        child: personListTile(person),
      ),
    );

    if((filter.isNotEmpty)) 
      List<Person> tmpList = new List<Person>();
      for(int i = 0; i < _filteredList.length; i++) 
        if(_filteredList[i].personFirstName.toLowerCase().startsWith(filter.toLowerCase())) 
          tmpList.add(_filteredList[i]);
        
      
      _filteredList = tmpList;
    

    final appBody = Container(
      child: ListView.builder(
        scrollDirection: Axis.vertical,
        shrinkWrap: true,
        itemCount: _personList == null ? 0 : _filteredList.length,
        itemBuilder: (BuildContext context, int index) 
          return personCard(_filteredList[index]);
        ,
      ),
    );

    return Scaffold(
      appBar: appTopAppBar,
      body: appBody,
    );
  


class PersonDataBuilder 
  List getPeople() 
    return [
      Person(
          personFirstName: "John",
          personLastName: "Smith"
      ),
      Person(
          personFirstName: "Alex",
          personLastName: "Johnson"
      ),
      Person(
          personFirstName: "Jane",
          personLastName: "Doe"
      ),
      Person(
          personFirstName: "Eric",
          personLastName: "Johnson"
      ),
      Person(
          personFirstName: "Michael",
          personLastName: "Eastwood"
      ),
      Person(
          personFirstName: "Benjamin",
          personLastName: "Woods"
      ),
      Person(
          personFirstName: "Abraham",
          personLastName: "Atwood"
      ),
      Person(
          personFirstName: "Anna",
          personLastName: "Clack"
      ),
      Person(
          personFirstName: "Clark",
          personLastName: "Phonye"
      ),
      Person(
          personFirstName: "Kerry",
          personLastName: "Mirk"
      ),
      Person(
          personFirstName: "Eliza",
          personLastName: "Wu"
      ),
      Person(
          personFirstName: "Jackey",
          personLastName: "Lee"
      ),
      Person(
          personFirstName: "Kristin",
          personLastName: "Munson"
      ),
      Person(
          personFirstName: "Oliver",
          personLastName: "Watson"
      ),

    ];
  


class Person 
  String personFirstName;
  String personLastName;

  Person(
    this.personFirstName, this.personLastName
  );

希望对大家有帮助,如有疑问请留言。 如果此答案对您有帮助,请不要忘记接受并投票。

【讨论】:

我不确定如何更改代码。请参阅 Rushikumar 8 月 14 日的回答。核心比较代码是: if((filter.isNotEmpty)) List tmpList = new List(); for(int i = 0; i 我已经编辑了我的答案并发布了完整的代码,您可以直接使用,请检查它,如果有任何疑问,请告诉我。 您修改后的代码完美运行,非常感谢克劳斯

以上是关于Flutter:按字符搜索列表的主要内容,如果未能解决你的问题,请参考以下文章

从非小部件类访问 Flutter Bloc

Flutter:如何在两个小部件之间传递相同的数据?

Flutter)我想知道如何通过按下按钮从创建的列表中删除项目

Flutter Hive:GroupBy 列表按日期

如何在 Flutter 中实现具有自动完成和搜索等功能的列表

Flutter - 实现 listView 搜索功能