首页 文章

带有自动完成功能的颤动搜索栏

提问于
浏览
2

我正在寻找flutter docs中的搜索栏,但无法找到它,是否有搜索栏的小部件,在appbar中自动完成 . 例如,我在appbar的顶部有图标搜索 . 当按下它显示搜索框时,开始输入时显示自动完成,就像下拉列表一样 . 我设法找到了这个但不容易使用,因为我需要下拉显示建议自动完成,然后使用建议选择新路由 .

Here the search action

here the example image what i want to achieve

1 回答

  • 1

    您可以使用Stack来实现自动完成下拉框效果 . 下面的示例有2个容器 - 都将 ListView 保存为子对象 . 一个包含搜索结果,另一个包含一些随机文本作为正文的内容 . ListView (搜索结果)放在对齐对象内,对齐属性设置为Alignment.topCenter . 这可确保List显示在 AppBar 正下方的顶部 .

    更新了评论中提到的Post(接受的答案)以获得完整的演示 .

    如上所述:

    @override
          Widget build(BuildContext context) {
            return new Scaffold(
                key: key,
                appBar: buildBar(context),
                body: new Stack(
                  children: <Widget>[
                    new Container(
                      height: 300.0,
                      padding: EdgeInsets.all(10.0),
                      child: new DefaultTabController(length: 5, child: mainTabView),
                    ),
                    displaySearchResults(),
                  ],
                ));
          }
    
    
          Widget displaySearchResults() {
            if (_IsSearching) {
              return new Align(
                  alignment: Alignment.topCenter,
                  //heightFactor: 0.0,
                  child: searchList());
            } else {
              return new Align(alignment: Alignment.topCenter, child: new Container());
            }
          }
    

    完整的演示

    class SearchList extends StatefulWidget {
      SearchList({Key key}) : super(key: key);
    
      @override
      _SearchListState createState() => new _SearchListState();
    }
    
    class _SearchListState extends State<SearchList> {
      Widget appBarTitle = new Text(
        "",
        style: new TextStyle(color: Colors.white),
      );
      Icon actionIcon = new Icon(
        Icons.search,
        color: Colors.white,
      );
      final key = new GlobalKey<ScaffoldState>();
      final TextEditingController _searchQuery = new TextEditingController();
      List<SearchResult> _list;
      bool _IsSearching;
      String _searchText = "";
      String selectedSearchValue = "";
    
      _SearchListState() {
        _searchQuery.addListener(() {
          if (_searchQuery.text.isEmpty) {
            setState(() {
              _IsSearching = false;
              _searchText = "";
            });
          } else {
            setState(() {
              _IsSearching = true;
              _searchText = _searchQuery.text;
            });
          }
        });
      }
    
      @override
      void initState() {
        super.initState();
        _IsSearching = false;
        createSearchResultList();
      }
    
      void createSearchResultList() {
        _list = <SearchResult>[
          new SearchResult(name: 'Google'),
          new SearchResult(name: 'IOS'),
          new SearchResult(name: 'IOS2'),
          new SearchResult(name: 'Android'),
          new SearchResult(name: 'Dart'),
          new SearchResult(name: 'Flutter'),
          new SearchResult(name: 'Python'),
          new SearchResult(name: 'React'),
          new SearchResult(name: 'Xamarin'),
          new SearchResult(name: 'Kotlin'),
          new SearchResult(name: 'Java'),
          new SearchResult(name: 'RxAndroid'),
        ];
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
            key: key,
            appBar: buildBar(context),
            body: new Stack(
              children: <Widget>[
                new Container(
                  height: 300.0,
                  padding: EdgeInsets.all(10.0),
                  child: new Container(
                    child: ListView(
                      children: <Widget>[
                        new Text("Hello World!"),
                        new Text("Hello World!"),
                        new Text("Hello World!"),
                        new Text("Hello World!"),
                        new Text("Hello World!"),
                        new Text("Hello World!"),
                        new Text("Hello World!"),
                        new Text("Hello World!"),
                        new Text("Hello World!"),
                        new Text("Hello World!"),
                        new Text("Hello World!"),
                        new Text("Hello World!"),
                        new Text("Hello World!"),
                      ],
                    ),
                  ),
                ),
                displaySearchResults(),
              ],
            ));
      }
    
      Widget displaySearchResults() {
        if (_IsSearching) {
          return new Align(
              alignment: Alignment.topCenter,
              child: searchList());
        } else {
          return new Align(alignment: Alignment.topCenter, child: new Container());
        }
      }
    
      ListView searchList() {
        List<SearchResult> results = _buildSearchList();
        return ListView.builder(
          itemCount: _buildSearchList().isEmpty == null ? 0 : results.length,
          itemBuilder: (context, int index) {
            return Container(
              decoration: new BoxDecoration(
                  color: Colors.grey[100],
                border: new Border(
                  bottom: new BorderSide(
                      color: Colors.grey,
                    width: 0.5
                  )
              )
              ),
    
              child: ListTile(
                onTap: (){},
                title: Text(results.elementAt(index).name,
                    style: new TextStyle(fontSize: 18.0)),
              ),
            );
          },
        );
      }
    
      List<SearchResult> _buildList() {
        return _list.map((result) => new SearchResult(name: result.name)).toList();
      }
    
      List<SearchResult> _buildSearchList() {
        if (_searchText.isEmpty) {
          return _list.map((result) => new SearchResult(name: result.name)).toList();
        } else {
          List<SearchResult> _searchList = List();
          for (int i = 0; i < _list.length; i++) {
            SearchResult result = _list.elementAt(i);
            if ((result.name).toLowerCase().contains(_searchText.toLowerCase())) {
              _searchList.add(result);
            }
          }
          return _searchList
              .map((result) => new SearchResult(name: result.name))
              .toList();
        }
      }
    
      Widget buildBar(BuildContext context) {
        return new AppBar(
          centerTitle: true,
          title: appBarTitle,
          actions: <Widget>[
            new IconButton(
              icon: actionIcon,
              onPressed: () {
                _displayTextField();
              },
            ),
    
            // new IconButton(icon: new Icon(Icons.more), onPressed: _IsSearching ? _showDialog(context, _buildSearchList()) : _showDialog(context,_buildList()))
          ],
        );
      }
    
      String selectedPopupRoute = "My Home";
      final List<String> popupRoutes = <String>[
        "My Home",
        "Favorite Room 1",
        "Favorite Room 2"
      ];
    
      void _displayTextField() {
        setState(() {
          if (this.actionIcon.icon == Icons.search) {
            this.actionIcon = new Icon(
              Icons.close,
              color: Colors.white,
            );
            this.appBarTitle = new TextField(
              autofocus: true,
              controller: _searchQuery,
              style: new TextStyle(
                color: Colors.white,
              ),
            );
    
            _handleSearchStart();
          } else {
            _handleSearchEnd();
          }
        });
      }
    
      void _handleSearchStart() {
        setState(() {
          _IsSearching = true;
        });
      }
    
      void _handleSearchEnd() {
        setState(() {
          this.actionIcon = new Icon(
            Icons.search,
            color: Colors.white,
          );
          this.appBarTitle = new Text(
            "",
            style: new TextStyle(color: Colors.white),
          );
          _IsSearching = false;
          _searchQuery.clear();
        });
      }
    }
    

相关问题