Элементы поиска не отображаются во время поиска в SearchBar во Flutter?

Я хочу добавить панель поиска во 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 class.


person Mr. Stark    schedule 03.07.2018    source источник
comment
Теперь у вас есть два разных класса под названием «AllBlogs»! У вас есть StatefulWidget и класс, содержащий id, blogName и т. Д. Переименуйте один из них.   -  person Richard Heap    schedule 06.07.2018
comment
Я уже переименовал «List ‹Blog› _displayList = allblogs» в «List ‹AllBlog› _displayList = allblogs», но столкнулся с проблемой, когда в «allblogs» говорилось, что «значение типа List не может быть присвоено переменной типа List class»   -  person Mr. Stark    schedule 06.07.2018
comment
Как называется класс вашего StatefulWidget?   -  person Richard Heap    schedule 06.07.2018
comment
Если я изменю «класс AllBlogs расширяет StatefulWidget» на «класс AllBlog расширяет StatefulWidget». Код не показывает ошибок, но когда я ищу, он всегда показывает один результат, независимо от того, какой запрос я набираю.   -  person Mr. Stark    schedule 06.07.2018
comment
Да, я сказал, что код не показывает ошибок, но во время поиска он всегда показывает первую.   -  person Mr. Stark    schedule 06.07.2018
comment
Можете ли вы подтвердить, что если вы дословно используете код в ответе, вы увидите ожидаемую фильтрацию?   -  person Richard Heap    schedule 06.07.2018
comment
Может быть, проблема в использовании более одного поля. Я также использую blogurl, about, url. и вы используете только один, то есть "blogName". Я думаю, что есть проблема с фильтрацией кода, потому что подсписок создается хорошо.   -  person Mr. Stark    schedule 06.07.2018
comment
Но фильтровать не умеет.   -  person Mr. Stark    schedule 06.07.2018
comment
Позвольте нам продолжить это обсуждение в чате.   -  person Richard Heap    schedule 06.07.2018


Ответы (1)


У вас есть List<Blog> где-то под названием allblogs. Каждый раз, когда текст поиска изменяется, формируется новый подсписок следующим образом:

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

(если поисковый текст пуст, просто назначьте все блоги в подсписок)

Теперь используйте sublist везде, где вы сейчас используете allblogs в своих сборках.

Таким образом, при каждом изменении критерия поиска вы фильтруете полный список до подсписка, который соответствует, и (пока вы делаете это в setState) дерево виджетов перерисовывается, показывая только отфильтрованный список.

Вот полный рабочий пример, основанный на приведенном выше фрагменте:

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();
              }
            });
          },
        ),
      ],
    );
  }
}
person Richard Heap    schedule 03.07.2018
comment
По-прежнему возникает проблема. Скажите, какой еще код вам нужен? - person Mr. Stark; 04.07.2018
comment
Снова в том же состоянии, я набираю текст в searchBar, но не ищу заголовок? - person Mr. Stark; 04.07.2018
comment
какой лучший подход к использованию _SearchListState? - person Mr. Stark; 04.07.2018
comment
попробуйте приведенное выше как автономный пример - person Richard Heap; 05.07.2018