how to create toolbar searchview in flutter

前端 未结 6 1292
不思量自难忘°
不思量自难忘° 2020-12-02 13:19

i need to implement searchview in toolbar my app to achieve list view list filter. like below image, i searched lot still not get proper answer. Any help will be appreciated

相关标签:
6条回答
  • 2020-12-02 13:59

    You just need to alternate between the state whenever the user taps on the icon. Beside a little bit of refactoring an code cleaning on your side, this simple example should get you going.

    class SearchAppBar extends StatefulWidget {
      @override
      _SearchAppBarState createState() => new _SearchAppBarState();
    }
    
    class _SearchAppBarState extends State<SearchAppBar> {
      Widget appBarTitle = new Text("AppBar Title");
      Icon actionIcon = new Icon(Icons.search);
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            centerTitle: true,
            title:appBarTitle,
            actions: <Widget>[
              new IconButton(icon: actionIcon,onPressed:(){
              setState(() {
                         if ( this.actionIcon.icon == Icons.search){
                          this.actionIcon = new Icon(Icons.close);
                          this.appBarTitle = new TextField(
                            style: new TextStyle(
                              color: Colors.white,
    
                            ),
                            decoration: new InputDecoration(
                              prefixIcon: new Icon(Icons.search,color: Colors.white),
                              hintText: "Search...",
                              hintStyle: new TextStyle(color: Colors.white)
                            ),
                          );}
                          else {
                            this.actionIcon = new Icon(Icons.search);
                            this.appBarTitle = new Text("AppBar Title");
                          }
    
    
                        });
            } ,),]
          ),
        );
      }
    }
    
    0 讨论(0)
  • 2020-12-02 14:09

    If you want a simple search bar, you can do it with a customized TextField

    import 'package:flutter/material.dart';
    
    class SearchBar extends StatelessWidget {
      final void Function(String) onTextChange;
    
      SearchBar({ this.onTextChange });
    
      @override
      Widget build(BuildContext context) {
        return Container(
          height: 50,
          padding: EdgeInsets.all(8),
          child: TextField(
            onChanged: onTextChange,
            decoration: InputDecoration(
              fillColor: Colors.black.withOpacity(0.1),
              filled: true,
              prefixIcon: Icon(Icons.search),
              hintText: 'Search something ...',
              border: OutlineInputBorder(borderRadius: BorderRadius.circular(10), borderSide: BorderSide.none),
              contentPadding: EdgeInsets.zero
            )
          )
        );
      }
    }
    
    0 讨论(0)
  • 2020-12-02 14:13

    There's also the Flutter flutter_search_view_pk library you could use to implement the same sort of design that Youtube/Instagram uses.

    How to integrate and use?

    1 : Directly drag and drop the pk_search_bar directory into your Flutter project.

    2 : Create a Class SearchScreen and in build > Scaffold > child: SearchBar()

    Navigator.push(
      context,
      MaterialPageRoute(
          builder: (context) =>  SearchScreen()),
    );
    

    Example

      Widget searchBar(BuildContext context) {
       return SearchBar<CountryModel>(
       searchBarPadding: EdgeInsets.only(left: 5, right: 5, top: 10, bottom: 5),
       headerPadding: EdgeInsets.only(left: 0, right: 0),
       listPadding: EdgeInsets.only(left: 0, right: 0),
       hintText: "Search Placeholder",
       hintStyle: TextStyle(
        color: Colors.black54,
      ),
      textStyle: TextStyle(
        color: Colors.black,
        fontWeight: FontWeight.normal,
      ),
      iconActiveColor: Colors.deepPurple,
      shrinkWrap: true,
      mainAxisSpacing: 5,
      crossAxisSpacing: 5,
      suggestions: widget.countryModelList,
      cancellationWidget: Text("Cancel"),
      minimumChars: 1,
      emptyWidget: Center(
        child: Padding(
          padding: const EdgeInsets.only(left: 10, right: 10),
          child: Text("There is no any data found"),
        ),
      ),
      onError: (error) {
        return Center(
          child: Padding(
            padding: const EdgeInsets.only(left: 10, right: 10),
            child: Text("$error", textAlign: TextAlign.center),
          ),
        );
      },
      loader: Center(
        child: LoadingIndicator(),
      ),
      onSearch: getCountrySearchWithSuggestion, /// CountrySearch  // if 
       want to search with API then use thi ----> getCountryListFromApi
      onCancelled: () {
        Navigator.pop(context);
      },
      buildSuggestion: (CountryModel countryModel, int index) {
        return countryGenerateColumn(countryModel, index);
      },
      onItemFound: (CountryModel countryModel, int index) {
        return countryGenerateColumn(countryModel, index);
      },
    );
    }
    

    0 讨论(0)
  • 2020-12-02 14:15

    You can do by edit leading, title and actions of AppBar. As you can see bellow.

    appBar: new AppBar(
        leading: _isSearching ? const BackButton() : null,
        title: _isSearching ? _buildSearchField() : _buildTitle(context),
        actions: _buildActions(),
     ),
    

    You can see it here in detail. They guys have built a simple demo for that.

    0 讨论(0)
  • 2020-12-02 14:25

    With the help @aziza answer i write detail code snippet of search view with list filter below. it will help for others

    import 'package:flutter/material.dart';
    
    class SearchList extends StatefulWidget {
      SearchList({ Key key }) : super(key: key);
      @override
      _SearchListState createState() => new _SearchListState();
    
    }
    
    class _SearchListState extends State<SearchList>
    {
      Widget appBarTitle = new Text("Search Sample", 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<String> _list;
      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() {
        super.initState();
        _IsSearching = false;
        init();
    
      }
    
      void init() {
        _list = List();
        _list.add("Google");
        _list.add("IOS");
        _list.add("Andorid");
        _list.add("Dart");
        _list.add("Flutter");
        _list.add("Python");
        _list.add("React");
        _list.add("Xamarin");
        _list.add("Kotlin");
        _list.add("Java");
        _list.add("RxAndroid");
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          key: key,
          appBar: buildBar(context),
          body: new ListView(
            padding: new EdgeInsets.symmetric(vertical: 8.0),
            children: _IsSearching ? _buildSearchList() : _buildList(),
          ),
        );
      }
    
      List<ChildItem> _buildList() {
        return _list.map((contact) => new ChildItem(contact)).toList();
      }
    
      List<ChildItem> _buildSearchList() {
        if (_searchText.isEmpty) {
          return _list.map((contact) => new ChildItem(contact))
              .toList();
        }
        else {
          List<String> _searchList = List();
          for (int i = 0; i < _list.length; i++) {
            String  name = _list.elementAt(i);
            if (name.toLowerCase().contains(_searchText.toLowerCase())) {
              _searchList.add(name);
            }
          }
          return _searchList.map((contact) => new ChildItem(contact))
              .toList();
        }
      }
    
      Widget buildBar(BuildContext context) {
        return new AppBar(
            centerTitle: true,
            title: appBarTitle,
            actions: <Widget>[
              new IconButton(icon: actionIcon, onPressed: () {
                setState(() {
                  if (this.actionIcon.icon == Icons.search) {
                    this.actionIcon = new Icon(Icons.close, color: Colors.white,);
                    this.appBarTitle = new TextField(
                      controller: _searchQuery,
                      style: new TextStyle(
                        color: Colors.white,
    
                      ),
                      decoration: new InputDecoration(
                          prefixIcon: new Icon(Icons.search, color: Colors.white),
                          hintText: "Search...",
                          hintStyle: 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("Search Sample", style: new TextStyle(color: Colors.white),);
          _IsSearching = false;
          _searchQuery.clear();
        });
      }
    
    }
    
    class ChildItem extends StatelessWidget {
      final String name;
      ChildItem(this.name);
      @override
      Widget build(BuildContext context) {
        return new ListTile(title: new Text(this.name));
      }
    
    }
    

    Output :

    0 讨论(0)
  • 2020-12-02 14:26

    You should use SearchDelegate which comes out of the box with Flutter. Here is a small video how it works:


    Full solution:

    class SearchPage extends StatefulWidget {
      @override
      _SearchPageState createState() => _SearchPageState();
    }
    
    class _SearchPageState extends State<SearchPage> {
      String _result;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text("Search")),
          body: Center(
            child: Column(
              children: <Widget>[
                Text(_result ?? "", style: TextStyle(fontSize: 18)),
                RaisedButton(
                  onPressed: () async {
                    var result = await showSearch<String>(
                      context: context,
                      delegate: CustomDelegate(),
                    );
                    setState(() {
                      _result = result;
                    });
                  },
                  child: Text("Search"),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class CustomDelegate<T> extends SearchDelegate<T> {
      List<String> data = nouns.take(100).toList();
    
      @override
      List<Widget> buildActions(BuildContext context) => [IconButton(icon: Icon(Icons.clear), onPressed: () => query = '')];
    
      @override
      Widget buildLeading(BuildContext context) => IconButton(icon: Icon(Icons.chevron_left), onPressed: () => close(context, null));
    
      @override
      Widget buildResults(BuildContext context) => Container();
    
      @override
      Widget buildSuggestions(BuildContext context) {
        var listToShow;
        if (query.isNotEmpty)
          listToShow = data.where((e) => e.contains(query) && e.startsWith(query)).toList();
        else
          listToShow = data;
    
        return ListView.builder(
          itemCount: listToShow.length,
          itemBuilder: (_, i) {
            var noun = listToShow[i];
            return ListTile(
              title: Text(noun),
              onTap: () => close(context, noun),
            );
          },
        );
      }
    }
    
    0 讨论(0)
提交回复
热议问题