在Flutter的SearchBar中搜索期间,搜索项没有显示出来吗?

时间:2018-07-03 22:47:40

标签: flutter flutter-layout flutter-animation

我想在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的标题进行比较,并显示匹配的图块。 Look The Image

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

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.",
  ),

当我尝试编写下面的代码时,然后在allblogs处显示错误信息:``无法将List类型的值分配给List类类型的变量。

1 个答案:

答案 0 :(得分:0)

您在某个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();
              }
            });
          },
        ),
      ],
    );
  }
}