Sunday, June 3, 2018

Flutter - Search widget on Appbar in Flutter

If you’re building a mobile application, then most likely you’ll need to implement a search feature in it to let the user search through a set of data that could be emails, messages, chats, photos, files, etc. 

Flutter provides us various widget for achieving it. Here, we going to use TextField to build search widget in Appbar. Appbar is the preferred way to use this widget to provide search feature in our application. It provides a user interface for the user to enter a search query and submit the request.

In this tutorial, we build search box in app bar that will open when we click on the search icon. Here, user can type a query for search. 

The final widget will look like.



>
Let's start it with modification of build method of state class.

1. Here, we going to build a base of Application. As you can see, I'm using leading, title and action param of App-bar that will update the widget when we change the state of _isSearching.
build method
@override Widget build(BuildContext context) { return new Scaffold( key: scaffoldKey, appBar: new AppBar( leading: _isSearching ? const BackButton() : null, title: _isSearching ? _buildSearchField() : _buildTitle(context), actions: _buildActions(), ), body: new Center( child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Text( '$searchQuery', style: Theme.of(context).textTheme.display1, ), ], ), ), ); }
In the center of the screen, we managing a text that will show the query of the search box.

2. Create a _startSearch method that will be invoked when open search box.
open search box
void _startSearch() { print("open search box"); ModalRoute .of(context) .addLocalHistoryEntry(new LocalHistoryEntry(onRemove: _stopSearching)); setState(() { _isSearching = true; }); }

3. Now, create a search box widget.
Search box
Widget _buildSearchField() { return new TextField( controller: _searchQuery, autofocus: true, decoration: const InputDecoration( hintText: 'Search...', border: InputBorder.none, hintStyle: const TextStyle(color: Colors.white30), ), style: const TextStyle(color: Colors.white, fontSize: 16.0), onChanged: updateSearchQuery, ); };
4. Create query update method that will show query when the user types something.
show update of query search
void updateSearchQuery(String newQuery) { setState(() { searchQuery = newQuery; }); print("search query " + newQuery); }



5. After that create an action method that will return the widget on app bar state change and search icon state.
Action method
List<Widget> _buildActions() { if (_isSearching) { return <Widget>[ new IconButton( icon: const Icon(Icons.clear), onPressed: () { if (_searchQuery == null || _searchQuery.text.isEmpty) { Navigator.pop(context); return; } _clearSearchQuery(); }, ), ]; } return <Widget>[ new IconButton( icon: const Icon(Icons.search), onPressed: _startSearch, ), ]; }


Now, Let's merge all the above widget and method in main.dart as I have created the final main.dart file.

main.dart
import 'dart:io'; import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( theme: new ThemeData( primarySwatch: Colors.blue, ), home: new MainPage(), ); } } class MainPage extends StatefulWidget { const MainPage(); @override _MainPageState createState() => new _MainPageState(); } class _MainPageState extends State<MainPage> with SingleTickerProviderStateMixin { static final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>(); TextEditingController _searchQuery; bool _isSearching = false; String searchQuery = "Search query"; @override void initState() { super.initState(); _searchQuery = new TextEditingController(); } void _startSearch() { print("open search box"); ModalRoute .of(context) .addLocalHistoryEntry(new LocalHistoryEntry(onRemove: _stopSearching)); setState(() { _isSearching = true; }); } void _stopSearching() { _clearSearchQuery(); setState(() { _isSearching = false; }); } void _clearSearchQuery() { print("close search box"); setState(() { _searchQuery.clear(); updateSearchQuery("Search query"); }); } Widget _buildTitle(BuildContext context) { var horizontalTitleAlignment = Platform.isIOS ? CrossAxisAlignment.center : CrossAxisAlignment.start; return new InkWell( onTap: () => scaffoldKey.currentState.openDrawer(), child: new Padding( padding: const EdgeInsets.symmetric(horizontal: 12.0), child: new Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: horizontalTitleAlignment, children: <Widget>[ const Text('Seach box'), ], ), ), ); } Widget _buildSearchField() { return new TextField( controller: _searchQuery, autofocus: true, decoration: const InputDecoration( hintText: 'Search...', border: InputBorder.none, hintStyle: const TextStyle(color: Colors.white30), ), style: const TextStyle(color: Colors.white, fontSize: 16.0), onChanged: updateSearchQuery, ); } void updateSearchQuery(String newQuery) { setState(() { searchQuery = newQuery; }); print("search query " + newQuery); } List<Widget> _buildActions() { if (_isSearching) { return <Widget>[ new IconButton( icon: const Icon(Icons.clear), onPressed: () { if (_searchQuery == null || _searchQuery.text.isEmpty) { Navigator.pop(context); return; } _clearSearchQuery(); }, ), ]; } return <Widget>[ new IconButton( icon: const Icon(Icons.search), onPressed: _startSearch, ), ]; } @override Widget build(BuildContext context) { return new Scaffold( key: scaffoldKey, appBar: new AppBar( leading: _isSearching ? const BackButton() : null, title: _isSearching ? _buildSearchField() : _buildTitle(context), actions: _buildActions(), ), body: new Center( child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Text( '$searchQuery', style: Theme.of(context).textTheme.display1, ), ], ), ), ); } }

Put above main.dart file in the project and run. Now, Let's use it and view the action of the search box.





That's all about the search box with app bar, but still, if have any query. Please feel free to clarify it with comment section below. 




Share:

Get it on Google Play

React Native - Start Development with Typescript

React Native is a popular framework for building mobile apps for both Android and iOS. It allows developers to write JavaScript code that ca...