0

我想在 Flutter 中添加搜索栏。而且我已经实现了可以在搜索栏中输入内容但在编写查询期间列表没有更新的状态。

我想根据 blogName 排序,下面是代码

class AllBlogs extends StatefulWidget {
  AllBlogs({Key key}) : super(key: key);


  final Color _tabBackgroudColor = const Color(0xFF1A237E);

  @override
  AllBlogsState createState() {
    return new AllBlogsState();
  }
}

class AllBlogsState extends State<AllBlogs> {

  Widget appBarTitle = Text("Blog's List");
  Icon actionIcon = Icon(Icons.search, color: Colors.white,);

  final key = new GlobalKey<ScaffoldState>();
  final TextEditingController _searchQuery = new TextEditingController();

  bool _IsSearching;
  String _searchText = "";



  _SearchListState() {
    _searchQuery.addListener(() {
      if (_searchQuery.text.isEmpty) {
        setState(() {
          _IsSearching = false;
          _searchText = "";
        });
      }
      else {
        setState(() {
          _IsSearching = true;
          _searchText = _searchQuery.text;
        });
      }
    });
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _IsSearching = false;

  }


  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: buildBar(context),

      body: new Container(
      color: Colors.transparent,
    child: ListView.builder(
    itemCount: allblogs.length,
    // Facing Issue Here
    itemBuilder: _IsSearching ? buildSearchList : blogslist
    ),
      ),
    );
  }

  // Facing Issue Here

  Widget buildSearchList(BuildContext context, int index){
     if (_searchText.isEmpty){
      return blogslist(context, index);
    }
    else {
       List<String> _searchList = List();
       for (int i = 0; i < allblogs.length; i++) {
         String name = (allblogs[index].blogName);
         if (name.toLowerCase().contains(_searchText.toLowerCase())) {
           _searchList.add(name);
         }
       }

      // Now what can i return to show the tile whoes blogName I searched for

       );

     }




  }



  Widget buildBar(BuildContext context) {
    return AppBar(
      centerTitle: true,
      title: appBarTitle,
      backgroundColor: widget._tabBackgroudColor,
      actions: <Widget>[
        IconButton(icon: actionIcon,
          onPressed: () {
            setState(() {
              if (this.actionIcon.icon == Icons.search) {
                // ignore: new_with_non_type
                this.actionIcon = new Icon(Icons.close, color: Colors.white,);
                this.appBarTitle = TextField(
                  controller: _searchQuery,
                  style: TextStyle(
                    color: Colors.white,
                  ),
                  decoration: InputDecoration(

                      prefixIcon: new Icon(Icons.search, color: Colors.white),
                      hintText: "Search...",
                      hintStyle: TextStyle(color: Colors.white)
                  ),
                );
                _handleSearchStart();
              }
              else {
                _handleSearchEnd();
              }
            });
          },),
      ],
    );
  }


  void _handleSearchStart() {
    setState(() {

      _IsSearching = true;

    });
  }

  void _handleSearchEnd() {
    setState(() {
      // ignore: new_with_non_type
      this.actionIcon =  new Icon(Icons.search, color: Colors.white,);
      this.appBarTitle = new Text("Search Sample", style: TextStyle(
        color: Colors.white,
      ),);
      _IsSearching = false;
      _searchQuery.clear();
    });
  }


}




Widget blogslist(BuildContext context, int index){

  return Container(
    padding: const EdgeInsets.only(top: 5.0),
    child: Column(
      children: <Widget>[
        ListTile(
          leading: Padding(
            padding: const EdgeInsets.all(3.0),
            child: new Image(image: AssetImage("assets/images/icons/stackexchange.png")),

          ),
          title: Text(allblogs[index].blogName,
            ),
          subtitle: Text(allblogs[index].blogName),
          contentPadding: EdgeInsets.symmetric(horizontal: 3.0),
          isThreeLine: true,
          trailing: Padding(padding: const EdgeInsets.only(left: 5.0),
            child: IconButton(icon: Icon(Icons.launch, color: Colors.blue, size: 20.0,),
                onPressed: (){}),
          ),
        ),


        Divider(),
      ],
    ),

  );
}

我想要的只是根据标题在颤振中搜索 ListTile 小部件 您还可以看到我上传的图像,显​​示我实现了可以在搜索栏中输入内容的情况。现在我只需要将输入文本与 ListTile 的标题进行比较,并显示匹配的图块。 看图像

我在不同的类中创建了一个列表,例如----

class AllBlogs {
  final String id;
  final String blogName;
  final String blogurl;
  final String about;

  const AllBlogs(
      {@required this.id,
      @required this.blogName,
      @required this.blogurl,
      @required this.about});
}

List<AllBlogs> allblogs = [
  const AllBlogs(
    id: '1',
    blogName: 'KDnuggets',
    blogurl: "https://www.kdnuggets.com/?ref=cybrhome",
    about: "KDnuggets is one of the most popular data science blogs, with articles that cover Business Analytics, Statistics, and Machine Learning.",
  ),

当我尝试在下面的代码中编写所有博客时。它显示错误“无法将 List 类型的值分配给 List 类类型的变量。

4

1 回答 1

1

你有一个List<Blog>地方叫allblogs. 每次搜索文本更改时都会形成一个新的子列表,如下所示:

List<Blog> sublist = allblogs.where((b) => b.name.toLowerCase().contains(_searchText.toLowerCase())).toList();

(如果搜索文本为空,则只需将所有博客分配给子列表)

现在使用sublist您当前allblogs在构建中使用的任何地方。

因此,在每次更改搜索条件时,您都会将完整列表过滤到匹配的子列表,并且(只要您在 setState 中这样做)Widget 树会重绘,仅显示过滤后的列表。

这是基于您上面的代码段的完整工作示例:

import 'package:flutter/material.dart';

main() {
  runApp(new MaterialApp(
    title: 'Blogs Test',
    home: new AllBlogs(),
  ));
}

class Blog {
  String blogName;

  Blog(this.blogName);
}

List<Blog> allblogs = [
  Blog('flutter'),
  Blog('dart'),
  Blog('java'),
  Blog('python'),
];

class AllBlogs extends StatefulWidget {
  AllBlogs({Key key}) : super(key: key);

  final Color _tabBackgroundColor = const Color(0xFF1A237E);

  @override
  AllBlogsState createState() => AllBlogsState();
}

class AllBlogsState extends State<AllBlogs> {
  Widget appBarTitle = Text("Blog's List");
  Icon actionIcon = Icon(
    Icons.search,
    color: Colors.white,
  );

  final key = new GlobalKey<ScaffoldState>();
  final TextEditingController _searchQuery = new TextEditingController();

  List<Blog> _displayList = allblogs;

  @override
  void initState() {
    super.initState();
    _searchQuery.addListener(() {
      if (_searchQuery.text.isEmpty) {
        setState(() {
          _displayList = allblogs;
        });
      } else {
        setState(() {
          String s = _searchQuery.text;
          _displayList = allblogs
              .where((b) => b.blogName.toLowerCase().contains(s.toLowerCase()))
              .toList();
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: buildBar(context),
      body: new Container(
        color: Colors.transparent,
        child: ListView.builder(
          itemCount: _displayList.length,
          itemBuilder: _blogBuilder,
        ),
      ),
    );
  }

  Widget _blogBuilder(BuildContext context, int index) {
    return Container(
      padding: const EdgeInsets.only(top: 5.0),
      child: Column(
        children: <Widget>[
          ListTile(
            leading: Padding(
              padding: const EdgeInsets.all(3.0),
              child: new Image(
                  image: AssetImage("assets/images/icons/stackexchange.png")),
            ),
            title: Text(_displayList[index].blogName),
            subtitle: Text(_displayList[index].blogName),
            contentPadding: EdgeInsets.symmetric(horizontal: 3.0),
            isThreeLine: true,
            trailing: Padding(
              padding: const EdgeInsets.only(left: 5.0),
              child: IconButton(
                  icon: Icon(
                    Icons.launch,
                    color: Colors.blue,
                    size: 20.0,
                  ),
                  onPressed: () {}),
            ),
          ),
          Divider(),
        ],
      ),
    );
  }

  Widget buildBar(BuildContext context) {
    return AppBar(
      centerTitle: true,
      title: appBarTitle,
      backgroundColor: widget._tabBackgroundColor,
      actions: <Widget>[
        IconButton(
          icon: actionIcon,
          onPressed: () {
            setState(() {
              if (this.actionIcon.icon == Icons.search) {
                this.actionIcon = new Icon(
                  Icons.close,
                  color: Colors.white,
                );
                this.appBarTitle = TextField(
                  controller: _searchQuery,
                  style: TextStyle(
                    color: Colors.white,
                  ),
                  decoration: InputDecoration(
                      prefixIcon: new Icon(Icons.search, color: Colors.white),
                      hintText: "Search...",
                      hintStyle: TextStyle(color: Colors.white)),
                );
              } else {
                this.actionIcon = new Icon(
                  Icons.search,
                  color: Colors.white,
                );
                this.appBarTitle = new Text(
                  "Search Sample",
                  style: TextStyle(
                    color: Colors.white,
                  ),
                );
                _searchQuery.clear();
              }
            });
          },
        ),
      ],
    );
  }
}
于 2018-07-03T23:12:59.813 回答