【问题标题】:How to implement a search bar in the appBar for a gridview list in flutter如何在appBar中为flutter中的gridview列表实现搜索栏
【发布时间】:2020-06-19 01:42:41
【问题描述】:

我有一个网格视图,每个视图都有标题,我想在 appBar 中实现一个搜索栏,我一直在搜索网络但找不到可以使用的东西,

【问题讨论】:

    标签: flutter flutter-layout flutter-dependencies


    【解决方案1】:

    您可以在下面复制粘贴运行完整代码
    当搜索文本更改返回searchList时,您可以addListenerTextEditingController

    代码sn-p

    final TextEditingController _searchQuery = TextEditingController();
    ...
    _searchQuery.addListener(() {
          if (_searchQuery.text.isEmpty) {
            setState(() {
              _IsSearching = false;
              _searchText = "";
              _buildSearchList();
            });
          } else {
            setState(() {
              _IsSearching = true;
              _searchText = _searchQuery.text;
              _buildSearchList();
            });
          }
        });
    ... 
    List<Model> _buildSearchList() {
        if (_searchText.isEmpty) {
          return _searchList = _list;
        } else {
          _searchList = _list
              .where((element) =>
                  element.name.toLowerCase().contains(_searchText.toLowerCase()) ||
                  element.title.toLowerCase().contains(_searchText.toLowerCase()))
              .toList();
          print('${_searchList.length}');
          return _searchList;
        }
      }
    ...
    GridView.builder(
                itemCount: _searchList.length,
                itemBuilder: (context, index) {
                  return GridItem(_searchList[index]);
                },  
    

    工作演示

    完整代码

    import 'package:flutter/material.dart';
    
    class Model {
      String id;
      String name;
      String title;
    
      Model({this.id, this.name, this.title});
    }
    
    class SearchList extends StatefulWidget {
      SearchList({Key key}) : super(key: key);
      @override
      _SearchListState createState() => _SearchListState();
    }
    
    class _SearchListState extends State<SearchList> {
      Widget appBarTitle = Text(
        "Search Demo",
        style: TextStyle(color: Colors.white),
      );
      Icon actionIcon = Icon(
        Icons.search,
        color: Colors.orange,
      );
      final key = GlobalKey<ScaffoldState>();
      final TextEditingController _searchQuery = TextEditingController();
      List<Model> _list;
      List<Model> _searchList = List();
    
      bool _IsSearching;
      String _searchText = "";
    
      @override
      void initState() {
        super.initState();
        _IsSearching = false;
        init();
      }
    
      void init() {
        _list = List();
        _list.add(
          Model(id: "1", name: "name 1", title: "a title 1"),
        );
        _list.add(
          Model(id: "2", name: "name 2", title: "a title 2"),
        );
        _list.add(
          Model(id: "3", name: "name 3", title: "b title 3"),
        );
        _list.add(
          Model(id: "4", name: "name 4", title: "b title 4"),
        );
        _list.add(
          Model(id: "5", name: "name 5", title: "b title 5"),
        );
        _searchList = _list;
    
        _searchQuery.addListener(() {
          if (_searchQuery.text.isEmpty) {
            setState(() {
              _IsSearching = false;
              _searchText = "";
              _buildSearchList();
            });
          } else {
            setState(() {
              _IsSearching = true;
              _searchText = _searchQuery.text;
              _buildSearchList();
            });
          }
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            key: key,
            appBar: buildBar(context),
            body: GridView.builder(
                itemCount: _searchList.length,
                itemBuilder: (context, index) {
                  return GridItem(_searchList[index]);
                },
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 3,
                )));
      }
    
      List<Model> _buildSearchList() {
        if (_searchText.isEmpty) {
          return _searchList = _list;
        } else {
          _searchList = _list
              .where((element) =>
                  element.name.toLowerCase().contains(_searchText.toLowerCase()) ||
                  element.title.toLowerCase().contains(_searchText.toLowerCase()))
              .toList();
          print('${_searchList.length}');
          return _searchList;
        }
      }
    
      Widget buildBar(BuildContext context) {
        return AppBar(
            centerTitle: true,
            title: appBarTitle,
            iconTheme: IconThemeData(color: Colors.orange),
            backgroundColor: Colors.black,
            actions: <Widget>[
              IconButton(
                icon: actionIcon,
                onPressed: () {
                  setState(() {
                    if (this.actionIcon.icon == Icons.search) {
                      this.actionIcon = Icon(
                        Icons.close,
                        color: Colors.orange,
                      );
                      this.appBarTitle = TextField(
                        controller: _searchQuery,
                        style: TextStyle(
                          color: Colors.orange,
                        ),
                        decoration: InputDecoration(
                            hintText: "Search here..",
                            hintStyle: TextStyle(color: Colors.white)),
                      );
                      _handleSearchStart();
                    } else {
                      _handleSearchEnd();
                    }
                  });
                },
              ),
            ]);
      }
    
      void _handleSearchStart() {
        setState(() {
          _IsSearching = true;
        });
      }
    
      void _handleSearchEnd() {
        setState(() {
          this.actionIcon = Icon(
            Icons.search,
            color: Colors.orange,
          );
          this.appBarTitle = Text(
            "Search Demo",
            style: TextStyle(color: Colors.white),
          );
          _IsSearching = false;
          _searchQuery.clear();
        });
      }
    }
    
    class GridItem extends StatelessWidget {
      final Model model;
      GridItem(this.model);
    
      Widget build(BuildContext context) {
        return Card(
          margin: EdgeInsets.fromLTRB(5, 5, 5, 7),
          elevation: 10.0,
          child: InkWell(
            splashColor: Colors.orange,
            onTap: () {
              print(model.id);
            },
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                AspectRatio(
                  aspectRatio: 18.0 / 11.0,
                  child: Image.network(
                    'https://picsum.photos/250?image=9',
                    fit: BoxFit.scaleDown,
                  ),
                ),
                Padding(
                  padding: EdgeInsets.fromLTRB(10.0, 15.0, 0.0, 0.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Text(
                        this.model.name,
                        style: TextStyle(
                            fontFamily: 'Raleway',
                            fontWeight: FontWeight.bold,
                            fontSize: 14.0),
                        maxLines: 1,
                      ),
                      SizedBox(height: 0.0),
                      Text(
                        model.title,
                        style: TextStyle(fontFamily: 'Roboto'),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: SearchList(),
        );
      }
    }
    

    【讨论】:

    • 谢谢你的回答,我怎样才能为 gridview 的每个元素制作不同的墨水池(点击),以导航到单独的页面?
    • 在 GridView.builder 中,您可以使用 Inkwell 包装 GridItem。
    • 原谅我,但我很新,我尝试这样做,但这只会导航到所有卡片的第一页,我想要做的是为每个项目添加一个路线导航到不同的页面,(例如名称 1 将带我到第 1 页,名称 2 将带我到第 2 页)
    • 很抱歉坚持,但如果可能的话,一个可行的例子真的会有所帮助
    • 我已经回答了你的新问题。请检查一下。
    猜你喜欢
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 2020-03-13
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 2021-03-29
    • 2014-05-16
    相关资源
    最近更新 更多