flutter search bar

How to create a Search Bar in Flutter with examples

What is a search bar?

A search bar is a user interface element that allows the user to enter a search query and submit it to search a database or other information repository. Search bars are commonly used in web browsers, search engines, and app store apps to find specific information or content.

A search bar typically consists of a text field where the user can enter their search query, and a button or icon to submit the query. Some search bars also include additional features, such as autocomplete suggestions, filters, or recent searches.

In Flutter, you can implement a search bar using the TextField widget with the decoration attribute set to an InputDecoration with a hintText of “Search…” and a search icon or button as the prefixIcon or suffixIcon. You can customize the appearance and behaviour of the search bar by changing the properties of the TextField and the InputDecoration, as well as by adding additional widgets or callbacks.

flutter search bar

Search bar placement

The search bar in Flutter app can be placed in various locations depending on your design and user experience goals. Here are a few common places where you can include a search bar:

  1. App bar: You can add a search bar to the app bar of your app, as I described in my previous example. This is a convenient location for the search bar because it is always visible at the top of the screen. However, the app bar may not have enough space to display a full-fledged search bar, so you may want to consider using a floating search bar or a search drawer instead.
  2. Floating search bar: A floating search bar is a search bar that appears on top of the content of the app when the user scrolls down. This allows the user to access the search bar at any time, while also keeping the app bar uncluttered. To implement a floating search bar in Flutter, you can use a SliverAppBar widget with a floating attribute set to true.
  3. Search drawer: A search drawer is a full-screen search interface that is accessible from the app bar or a dedicated search button. This design allows the user to expand the search interface when needed while keeping the app bar uncluttered. To implement a search drawer in Flutter, you can use a Drawer widget with a search bar as the main content.
  4. Landing page: You can also place a search bar on the landing page of your app, especially if your app’s primary function is search. This allows the user to start searching as soon as they open the app.
  5. Screen bottom sheet: A screen bottom sheet is a full-screen interface that appears at the bottom of the screen when the user performs a specific action, such as tapping a button or selecting an item from a list. You can use a screen bottom sheet to display a search bar and other search-related elements, such as filters or recent searches. To implement a screen bottom sheet in Flutter, you can use a BottomSheet widget.
  6. And more 🙂

Simple Flutter Search Bar

Here is an example of how you could implement a search bar in Flutter:

flutter search bar
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        textTheme: const TextTheme(
          // bodyText2: TextStyle(color: Colors.red, fontWeight: FontWeight.w900),
        ),
      ),
      home: const MyHomePage(title: 'Flutter Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  // This controller will store the value of the search bar
  final TextEditingController _searchController = TextEditingController();

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: const Text('flutterassets.com'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Container(
          // Add padding around the search bar
          padding: const EdgeInsets.symmetric(horizontal: 8.0),
          // Use a Material design search bar
          child: TextField(
            controller: _searchController,
            decoration: InputDecoration(
              hintText: 'Search...',
              // Add a clear button to the search bar
              suffixIcon: IconButton(
                icon: Icon(Icons.clear),
                onPressed: () => _searchController.clear(),
              ),
              // Add a search icon or button to the search bar
              prefixIcon: IconButton(
                icon: Icon(Icons.search),
                onPressed: () {
                  // Perform the search here
                },
              ),
              border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(20.0),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

This search bar is implemented as a StatefulWidget because we want to store the value of the search bar in a TextEditingController. The search bar itself is a TextField with a hintText of “Search…” and a clear button as the suffixIcon. The prefixIcon is an IconButton with an Icon of a search icon. The search bar also has a border with rounded corners.

You can customize this search bar further by changing the appearance and behaviour of the TextField, such as the keyboardType or the onChanged callback. You can also use this search bar as a starting point and build upon it to create a more advanced search interface.

Search icon outside search border

Here is an example of how you can place a search icon outside the border of the search bar:

// This controller will store the value of the search bar
  final TextEditingController _searchController = TextEditingController();

Padding(
  padding: const EdgeInsets.all(8.0),
  child: Row(
    children: [
      // Add a search icon or button outside the border of the search bar
      IconButton(
        icon: Icon(Icons.search),
        onPressed: () {
          // Perform the search here
        },
      ),
      Expanded(
        // Use a Material design search bar
        child: TextField(
          controller: _searchController,
          decoration: InputDecoration(
            hintText: 'Search...',
            // Add a clear button to the search bar
            suffixIcon: IconButton(
              icon: Icon(Icons.clear),
              onPressed: () => _searchController.clear(),
            ),
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(20.0),
            ),
          ),
        ),
      ),
    ],
  ),
),
flutter search bar icon outside

I placed the search icon or button outside the border of the search bar by wrapping the search bar and the search icon or button in a Row widget and using an Expanded widget to occupy the remaining space. This allows the search bar to take up most of the available space, while the search icon or button is aligned to the right.

You can customize the appearance and behaviour of the search icon or button by changing the icon and onPressed callback, as well as the layout of the Row widget. You can also adjust the padding and spacing between the search bar and the search icon or button to achieve the desired look and feel.

Search bar in the AppBar in Flutter

You can place a search bar in the app bar in Flutter. Here is an example of how you can do this:

// This controller will store the value of the search bar
  final TextEditingController _searchController = TextEditingController();

appBar: AppBar(
  title: Container(
    // Add padding around the search bar
    padding: const EdgeInsets.symmetric(horizontal: 8.0),
    // Use a Material design search bar
    child: TextField(
      controller: _searchController,
      decoration: InputDecoration(
        hintText: 'Search...',
        // Add a clear button to the search bar
        suffixIcon: IconButton(
          icon: Icon(Icons.clear, color: Colors.black,),
          onPressed: () => _searchController.clear(),
        ),
        // Add a search icon or button to the search bar
        prefixIcon: IconButton(
          icon: Icon(Icons.search, color: Colors.black,),
          onPressed: () {
            // Perform the search here
          },
        ),
        // border: OutlineInputBorder(
        //   borderRadius: BorderRadius.circular(20.0),
        // ),
      ),
    ),
  )
),
flutter search bar appbar

I added a search bar to the app bar by using a TextField widget as the title of the AppBar. The search bar has a hintText of “Search…” and a clear button as the suffixIcon.

You can customize the appearance and behaviour of the search bar by changing the properties of the TextField, such as the keyboardType or the onChanged callback. You can also add a search icon or button to the search bar, as I described in my previous examples.

Keep in mind that the app bar may not have enough space to display a full-fledged search bar, so you may want to consider using a floating search bar or a search drawer instead. These designs allow the user to expand the search interface when needed while keeping the app bar uncluttered.

Floating search bar in Flutter

Here is an example of how you can implement a floating search bar in Flutter:

// This controller will store the value of the search bar
  final TextEditingController _searchController = TextEditingController();

CustomScrollView(
  slivers: [
    // Add a floating search bar to the app
    SliverAppBar(
      floating: true,
      // Use a Material design search bar
      title: TextField(
        controller: _searchController,
        decoration: InputDecoration(
          hintText: 'Search...',
          // Add a clear button to the search bar
          suffixIcon: IconButton(
            icon: Icon(Icons.clear, color: Colors.black,),
            onPressed: () => _searchController.clear(),
          ),
        ),
      ),
    ),
    // Add a list of items to the app
    SliverList(
      delegate: SliverChildBuilderDelegate(
            (context, index) {
          return ListTile(
            title: Text('Item $index'),
          );
        },
        childCount: 20,
      ),
    ),
  ],
),
flutter search bar floating

In this example, I added a floating search bar to the app using a SliverAppBar widget with the floating attribute set to true. The search bar itself is a TextField with a hintText of “Search…” and a clear button as the suffixIcon.

The SliverAppBar widget is part of the CustomScrollView widget, which allows the search bar to float on top of the content of the app when the user scrolls down. The CustomScrollView also includes a SliverList widget with a list of items, which allows the user to scroll through the content and see the floating search bar.

You can customize the appearance and behaviour of the floating search bar by changing the properties of the TextField and the SliverAppBar, as well as by adding additional widgets or callbacks. For example, you can add a search icon or button to the search bar, or use the onChanged callback of the TextField to perform a search as the user types.

Sticky search bar in Flutter

Here is an example of a search bar that is always visible in Flutter:

// This controller will store the value of the search bar
  final TextEditingController _searchController = TextEditingController();
  final FocusNode _searchFocusNode = FocusNode();

Column(
  children: [
    // Add the floating search bar
    Container(
      height: 60,
      child: TextField(
        focusNode: _searchFocusNode,
        controller: _searchController,
        decoration: InputDecoration(
          prefixIcon: Icon(Icons.search),
          hintText: 'Search...',
          border: OutlineInputBorder(),
        ),
      ),
    ),
    Expanded(
      child: ListView.builder(
        itemCount: 20,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('Item $index'),
          );
        },
      ),
    ),
  ],
),
flutter search bar sticky

This example creates a Scaffold with a Column that contains a search bar and a list of items. The search bar is implemented using a TextField widget with a prefixIcon and a hintText to indicate its purpose and a border to give it a visual separation from the rest of the screen.

To make the search bar always visible, it is added to the top of the Column and given a fixed height. The list of items is added below the search bar and given the remaining space using the Expanded widget.

Create a Search drawer in Flutter

Here is an example of how to create a search drawer in Flutter:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        textTheme: const TextTheme(
          // bodyText2: TextStyle(color: Colors.red, fontWeight: FontWeight.w900),
        ),
      ),
      home: const MyHomePage(title: 'Flutter Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  // This controller will store the value of the search bar
  final TextEditingController _searchController = TextEditingController();
  final FocusNode _searchFocusNode = FocusNode();

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: const Text('flutterassets.com'),
      ),
      body: ListView.builder(
        itemCount: 20,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('Item $index'),
          );
        },
      ),
      drawer: SafeArea(
        child: Drawer(
          child: Column(
            children: [
              // Add the search bar to the drawer
              Container(
                height: 60,
                child: TextField(
                  focusNode: _searchFocusNode,
                  controller: _searchController,
                  decoration: InputDecoration(
                    prefixIcon: Icon(Icons.search),
                    hintText: 'Search...',
                    border: OutlineInputBorder(),
                  ),
                ),
              ),
              Expanded(
                child: ListView.builder(
                  itemCount: 5,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text('Drawer Item $index'),
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
flutter search bar drawer

This example creates a Scaffold with an app bar, a body, and a drawer. The body contains a list of items, and the drawer contains a search bar and a list of items.

The search bar is implemented using a TextField widget with a prefixIcon and a hintText to indicate its purpose and a border to give it a visual separation from the rest of the drawer. It is added to the top of the drawer’s Column and given a fixed height. The list of items is added below the search bar and given the remaining space using the Expanded widget.

To open and close the drawer, you can use the Drawer widget’s openEndDrawer and closeEndDrawer methods, respectively. You can also use the Scaffold widget’s drawer property to toggle the drawer open and closed by tapping on the app bar’s hamburger icon.

Search bar with showModalBottomSheet in Flutter

Here is an example of how to create a search bar in a bottom sheet in Flutter:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
textTheme: const TextTheme(
// bodyText2: TextStyle(color: Colors.red, fontWeight: FontWeight.w900),
),
),
home: const MyHomePage(title: 'Flutter Demo'),
);
}
}

class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;

@override
State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

// This controller will store the value of the search bar
final TextEditingController _searchController = TextEditingController();
final FocusNode _searchFocusNode = FocusNode();

void initState() {
SystemChannels.textInput.invokeMethod('TextInput.hide');
super.initState();
}

@override
Widget build(BuildContext context) {
// FocusScope.of(context).requestFocus(new FocusNode());

return Scaffold(
appBar: AppBar(
title: const Text('flutterassets.com'),
),
body: ListView.builder(
itemCount: 20,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item $index'),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// Show the bottom sheet with the search bar
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) {
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Container(
height: 60,
child: TextField(
autofocus: false,
focusNode: _searchFocusNode,
controller: _searchController,
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
hintText: 'Search...',
border: OutlineInputBorder(),
),
),
),
);
},
);
},
child: Icon(Icons.search),
),
);
}
}


flutter search bar bottom

This example creates a Scaffold with a body and a floating action button. The body contains a list of items, and the floating action button opens a bottom sheet with a search bar.

The search bar is implemented using a TextField widget with a prefixIcon and a hintText to indicate its purpose and a border to give it a visual separation from the rest of the bottom sheet.

To open the bottom sheet, the showModalBottomSheet function is called and passed a context and a builder function that returns the bottom sheet’s content. The bottom sheet can be closed by tapping outside of it or by pressing the device’s back button.

Search bar with FloatingActionButton in Flutter

To create a search bar inside a FloatingActionButton in Flutter, you can use a FloatingActionButton.extended widget and wrap the search bar inside the label property of the button.

flutter search bar floatingactionbutton
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        textTheme: const TextTheme(
          // bodyText2: TextStyle(color: Colors.red, fontWeight: FontWeight.w900),
        ),
      ),
      home: const MyHomePage(title: 'Flutter Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  // This controller will store the value of the search bar
  final TextEditingController _searchController = TextEditingController();
  bool _isExpanded = false;

  void initState() {
    SystemChannels.textInput.invokeMethod('TextInput.hide');
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: const Text('flutterassets.com'),
      ),
        body: GestureDetector(
          onTap: (){
            setState(() {
              _isExpanded = !_isExpanded;
            });
          },
          child: ListView.builder(
            itemCount: 20,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text('Item $index'),
              );
            },
          ),
        ),
        floatingActionButton: _isExpanded
          ? FloatingActionButton.extended(
            onPressed: () {
              // Perform search action
              setState(() {
                _isExpanded = !_isExpanded;
              });
            },
            label: Container(
              width: 250,
              child: TextField(
                controller: _searchController,
                decoration: const InputDecoration(
                  hintText: 'Search...',
                  border: InputBorder.none,
                ),
              ),
            ),
            icon: Icon(Icons.search),
          )
          : FloatingActionButton(
            onPressed: () {
              setState(() {
                _isExpanded = !_isExpanded;
              });
            },
            child: Icon(Icons.search),
          )
    );
  }
}

The search bar is implemented using a TextField widget inside a FloatingActionButton.extended. The search bar can be expanded and collapsed by pressing the button and the _isExpanded flag is used to toggle the visibility of the search bar. The _searchController is used to store the value of the search bar.

The ListView is wrapped in a GestureDetector, which allows the user to expand the search bar by tapping anywhere on the screen. When the user taps the screen, the _isExpanded flag is toggled and the search bar is shown or hidden.

Search bar with AlertDialog in Flutter

To create a search bar with an Alert dialog in Flutter, you can use an AlertDialog widget and wrap the search bar inside it.

flutter search bar alertdialog

Here’s an example of how you can achieve this:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        textTheme: const TextTheme(
          // bodyText2: TextStyle(color: Colors.red, fontWeight: FontWeight.w900),
        ),
      ),
      home: const MyHomePage(title: 'Flutter Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  // This controller will store the value of the search bar
  final TextEditingController _searchController = TextEditingController();

  void initState() {
    SystemChannels.textInput.invokeMethod('TextInput.hide');
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: const Text('flutterassets.com'),
      ),
        body: Container(
          padding: EdgeInsets.all(12),
          child: ElevatedButton(
            onPressed: () {
              showSearchDialog(context);
            },
            child: Text('Show search dialog'),
          ),
        ),
    );
  }

  void showSearchDialog(BuildContext context) {
      showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            alignment:  Alignment.topCenter,
            title: Text('Search'),
            content: TextField(
              controller: _searchController,
              decoration: InputDecoration(
                hintText: 'Enter search query...',
              ),
            ),
            actions: [
              TextButton(
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: Text('Cancel'),
              ),
              TextButton(
                onPressed: () {
                  // Perform search action
                  Navigator.of(context).pop();
                },
                child: Text('Search'),
              ),
            ],
          );
        },
      );
  }
}

This will create a button that, when pressed, shows an Alert dialog with a search bar inside it. The search bar will have a text field where the user can enter their search query. The user can then press the “Search” button to perform the search action, or the “Cancel” button to close the dialog.

The _searchController is used to store the value of the search bar. When the user presses the “Search” button, the onPressed callback is called, allowing you to perform the search action.