Search Bar in Flutter
Published: 2024-02-12 23:22:20


*Another variation in a common feature.*

Apps love their search bars. Every popular platform has a dedicated class to provide a search bar — all except Flutter it would seem. A search bar offers a means for the user to quickly search for content applicable to the app being used. Many articles have been written on the subject offering code that implements a search bar of one variation or another. Frankly, this article is no exception. Inspired by [Ahmed Al-Zahrani](https://medium.com/@ahmedalzahrani94)’s own article, [A simple Search Bar in Flutter](https://medium.com/flutterpub/a-simple-search-bar-in-flutter-f99aed68f523), I wrote a class that supplies yet another search bar for Flutter. The [source code](https://gist.github.com/Andrious/a2319a776cd96164db219ddf3a993740#file-appbar_search-dart) is available to you to do what you will. Make it your own. Make it better — and share if you’re so inclined.

This article will examine my version’s implementation and how it’s used. The article will supply some examples, and we’ll do a ‘walkthrough’ of the code.

![[Other Stories by Greg Perry](https://medium.com/p/9de112c2d85c/)](https://cdn-images-1.medium.com/max/3318/1*7W5QuSXbMy8bDD2aW1eLgg.png)

## Real Estate at a Premium

I needed a quick means for the user to perform a search in my apps. Again, inspired by Al-Zahrani’s work, I decided to utilize the title of the app itself and change it to a text field when the user wants to perform a search. The user needs only to tap on the title or tap on the little ‘magnifying glass’ displayed beside it to initiate a search routine. I wrote a class to do this.

Below is a screenshot of one of my apps demonstrating how one would implement this class. You can see the two functions highlighted below, **onTitle**() and **onSearchIcon**(), are used to provide this functionality. The **onTitle**() routine is used to change the provided title into a text field while the **onSearchIcon**() supplies the ‘Magnifying glass’ icon that can also initiate a search. Further, this second function allows you to supply the very routine called to perform the search. In the case of the example below, the user types in, “ibm”, and an assigned search routine presents several companies that use that term in their stock symbol.

![](https://cdn-images-1.medium.com/max/2880/1*qK4IrxaLG70IxB1kzPpmIw.png)

![](https://cdn-images-1.medium.com/max/2000/1*mEyADEUMh1I7RUvFfP6qPA.png)
<figcaption><a href="https://cdn-images-1.medium.com/max/2000/1*R2Rg5yl7oBn7Bcpd3RHHpg.gif">Demonstration</a></figcaption>

In the screenshot above, you see an AppBar is used. Merely two of its named parameters are involved in the ‘search bar’ capability. Below are two more screenshots. The one on the left is the example code again, but now you see the class, *AppBarSearch*, that’s involved in this, and you see it being instantiated in the **initState**() function. It takes in one parameter value — a reference to the State object itself. The screenshot on the right is the AppBarSearch class itself. Note, that a reference to a State object is the only required parameter.

![](https://cdn-images-1.medium.com/max/2886/1*RQWeFVwLFbcQC-rLq4ZCqg.png)

![](https://cdn-images-1.medium.com/max/2880/1*v1PTw-Aau93YRCf5bRFZgA.png)
<figcaption><a href="https://gist.github.com/Andrious/a2319a776cd96164db219ddf3a993740#file-appbar_search-dart-L3">appbar_search.dart</a></figcaption>

## Initiate Your Search

The left screenshot below is another variation of the example code above. It accomplishes the same thing as the first example, but both the ‘title’ and the ‘submit routine’ are now supplied in the **initState**() function as well. The two functions that were in the **build**() function are now replaced by the instance variable called, *title*, and the *getter *called, *searchIcon*. The screenshot on the right highlights that *getter *with a little red arrow in the AppBarSearch class.

![](https://cdn-images-1.medium.com/max/2880/1*63HnD29EiO8oS15TDovxJQ.png)

![](https://cdn-images-1.medium.com/max/2876/1*QJdKxvY6ktBF4M31kuP27Q.png)
<figcaption><a href="https://gist.github.com/Andrious/a2319a776cd96164db219ddf3a993740#file-appbar_search-dart-L57">appbar_search.dart</a></figcaption>

## Search Your Options

And so, you have your options. You can supply the title for your app in the **build**() function or define it where you instantiate the AppBarSearch class. Why do you have that option? Why not? There may be instances that such an option would prove a nice convenience or, in fact, a necessity.

## A Walkthrough

Let’s walk through the class, *AppBarSearch*, and give you some insight as to how it works and how the programming language, *Dart*, allows for an efficient and effective means to implement such a search bar in your app.

Again, there’s only one ‘required’ parameter for this class. Three of the remaining parameters are ‘callback’ routines used when the user is finished entering a value into the TextField widget. With regards to the parameter, *title*, if no widget is supplied, it‘s assigned a Text widget in the constructor. In fact, the instance variable is eventually assigned a GestureDetector widget allowing a user to initiate a search by tapping on the app’s title.

![](https://cdn-images-1.medium.com/max/2880/1*apWmNCu1QvZ2ySiA7J9Ubw.png)
<figcaption><a href="https://gist.github.com/Andrious/a2319a776cd96164db219ddf3a993740#file-appbar_search-dart-L3">appbar_search.dart</a></figcaption>

Note, that all the defined parameters are final instance variables except the parameter, *title*. Most are re-assigned to ‘private’ variables. It’s these private variables that are passed to the TextField widget involved in a search. Why the redundancy? It’s to preserve them once assigned through the constructor. The parameters can’t be reassigned since they’re ‘final’ external properties of the class. The only other way you can ‘override’ the callback routines, for example, is by using the function, **onSearchIcon**().

![](https://cdn-images-1.medium.com/max/2872/1*h3ovgXk9dfPTkW-klzvM1Q.png)
<figcaption><a href="https://gist.github.com/Andrious/a2319a776cd96164db219ddf3a993740#file-appbar_search-dart-L28">appbar_search.dart</a></figcaption>

You can see the ‘final’ instance variables listed above. The only property another developer can change before the **build**() function is called is the instance variable, *title*. The callback routines can not. Note, the text field’s controller can be assigned through the constructor. If one is not specified, however, a **TextEditingController **object is provided.

The function, **onTitle**(), is used to supply a ‘touchable’ title widget unless of course, a search is already underway. If there’s an ongoing search, the variable, *_wasPressed*, would be set to true and the function merely returns the currently assigned title. If a GestureDetector widget is passed to the function, it will be used instead. You’ve got that option.

Any parameters supplied to the function, **onSearchIcon**(), will override those supplied to the constructor. This function returns the same IconButton widget supplied by the *getter *called, *searchIcon*.

![](https://cdn-images-1.medium.com/max/2876/1*chh9Cm3yS_RhokreJ-6fdA.png)
<figcaption><a href="https://gist.github.com/Andrious/a2319a776cd96164db219ddf3a993740#file-appbar_search-dart-L57">appbar_search.dart</a></figcaption>

Unless otherwise specified with the parameter, *onPressed*, in the constructor, it’s the internal function, **_pressedFunc**(), that’s fired when the user taps on the app’s title. It’s this function that then changes the app’s title to a text field to initiate a search. A screenshot of this function is displayed below. If the current icon is the ‘search’ icon, the title widget is changed to the TextField widget, and the **build**() function is called again with **setState**((){}). When this function is then called again, the app’s title is returned.

![](https://cdn-images-1.medium.com/max/2876/1*gD_4rldsZYeu_JSUN5-Cug.png)
<figcaption><a href="https://gist.github.com/Andrious/a2319a776cd96164db219ddf3a993740#file-appbar_search-dart-L88">appbar_search.dart</a></figcaption>

The function, **_submitFunc**(), is called when the user has submitted a value from the text field. Note, it calls the function, **_pressedFunc**(), to return the app’s title and then fires the ‘submit’ routine if any.

## On The Flutter Side

Deep in the Flutter framework, you can see where those callback routines are finally called. If and when the user wants to use these callback routines, of course, they have the option to do so using this AppBarSearch class.

The callback routine, *onSubmitted*, is called when the user is done editing the text in the field. The value from the text field is passed to this routine. The callback routine, *onEditingComplete*, also runs when the user finishes editing. It overrides the default behavior where the user’s content is submitted to the controller and then focuses on the text field is given up. Applications that require different behavior override the callback routine, *onEditingComplete*.

![](https://cdn-images-1.medium.com/max/2882/1*fm1FvgIkPft_HJXP0XERxQ.png)
<figcaption><a href="https://github.com/flutter/flutter/blob/fabf4e3d0d311181178d2c601d29a2f739ea543a/packages/flutter/lib/src/widgets/editable_text.dart#L1333">editable_text.dart</a></figcaption>

## A Simple Search Bar Example

I’ve turned to [Ahmed Al-Zahrani](https://medium.com/@ahmedalzahrani94)’s own article for another example. I’ve modified his example to now use the class, *AppBarSearch*. There’s a copy for your review on [Github](https://gist.github.com/Andrious/70388b657a51b42e7599a459ff86c805#file-flutter_search_example-dart), and, of course, you have Ahmed’s [original example](https://github.com/ahmed-alzahrani/Flutter_Search_Example) to compare with if you feel the need. This example involves a very simple API call listing some characters found from the Star Wars franchise.

The AppBarSearch class takes in a TextEditingController object called, *_filter*, which, in this example, is the primary player in the search routine involved. Again, the class, *AppBarSearch*, takes care of changing the app’s title into a text field when tapped, but it’s the controller, *_filter*, that’s assigned a listener routine that ‘filter out’ character names containing the letters typed by the user.

![](https://cdn-images-1.medium.com/max/2870/1*Ja_NQTHNK09Vh_fJnvmsCA.png)

![](https://cdn-images-1.medium.com/max/2000/1*rhg15rj_SQIdqmBJMoG0KA.gif)
<figcaption><a href="https://gist.github.com/Andrious/70388b657a51b42e7599a459ff86c805#file-flutter_search_example-dart-L42">flutter_search_example.dart</a></figcaption>

The listener adds the typed characters to the instance variable, *_searchText*. With every build, the variable, *_searchText*, is evaluated in the function, **_buildList**() (see below) with the contents of the ListView widget adjusted accordingly. You can see, in this example, I chose to use the getter, *searchIcon.*

![](https://cdn-images-1.medium.com/max/2874/1*83xuVCW9zypdfQx00OnUrQ.png)
<figcaption><a href="https://gist.github.com/Andrious/70388b657a51b42e7599a459ff86c805#file-flutter_search_example-dart-L66">flutter_search_example.dart</a></figcaption>

So there you are. A search bar is a seemingly common feature in mobile apps. You’ve at least an option now if your next Flutter app requires such a feature.

Cheers.

[Greg Perry](https://dev.to/andrious)