How to create a Filter/Search ListView in Flutter

Updated: March 6, 2024 By: A Goodman 26 comments

This article is about making a filter/search ListView in Flutter. We will take a quick look at the approach to get the job done and then go through a concrete and complete example of applying that approach. No third-party packages are required.

Overview

We will create a function to filter the results, and this function will be called when the text field changes (onChanged). The search algorithm can be different on a case-by-case basis, but the simplest and most popular is to use the following Dart methods:

  • where(): Returns a new lazy Iterable with all elements that satisfy one or many conditions.
  • contains(): Used to determine whether a string contains another string (you can try other string methods like startsWith(), endsWith(), etc.)
  • toLowerCase(): This string method will convert all characters in this string to lowercase so that it doesn’t matter whether the search keyword is uppercase or lowercase.

These words can be confusing. See the example for more clarity.

Example

Let’s say we have a list of users with some information, including id, name, and age. In the beginning, all of these users are shown in a ListView. If you type something into the search field, only users whose names match the keyword will be displayed. If you clear the search field, the full list of users will appear again.

Preview

demo video (may not run on Safari)

The Code

The full source code in lib/main.dart with explanations in the comments (this code was updated to work properly with the latest version of Flutter):

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

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // This holds a list of fiction users
  // You can use data fetched from a database or a server as well
  final List<Map<String, dynamic>> _allUsers = [
    {"id": 1, "name": "Andy", "age": 29},
    {"id": 2, "name": "Aragon", "age": 40},
    {"id": 3, "name": "Bob", "age": 5},
    {"id": 4, "name": "Barbara", "age": 35},
    {"id": 5, "name": "Candy", "age": 21},
    {"id": 6, "name": "Colin", "age": 55},
    {"id": 7, "name": "Audra", "age": 30},
    {"id": 8, "name": "Banana", "age": 14},
    {"id": 9, "name": "Caversky", "age": 100},
    {"id": 10, "name": "Becky", "age": 32},
  ];

  // This list holds the data for the list view
  List<Map<String, dynamic>> _foundUsers = [];
  @override
  initState() {
    // at the beginning, all users are shown
    _foundUsers = _allUsers;
    super.initState();
  }

  // This function is called whenever the text field changes
  void _runFilter(String enteredKeyword) {
    List<Map<String, dynamic>> results = [];
    if (enteredKeyword.isEmpty) {
      // if the search field is empty or only contains white-space, we'll display all users
      results = _allUsers;
    } else {
      results = _allUsers
          .where((user) =>
              user["name"].toLowerCase().contains(enteredKeyword.toLowerCase()))
          .toList();
      // we use the toLowerCase() method to make it case-insensitive
    }

    // Refresh the UI
    setState(() {
      _foundUsers = results;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Kindacode.com'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(10),
        child: Column(
          children: [
            const SizedBox(
              height: 20,
            ),
            TextField(
              onChanged: (value) => _runFilter(value),
              decoration: const InputDecoration(
                  labelText: 'Search', suffixIcon: Icon(Icons.search)),
            ),
            const SizedBox(
              height: 20,
            ),
            Expanded(
              child: _foundUsers.isNotEmpty
                  ? ListView.builder(
                      itemCount: _foundUsers.length,
                      itemBuilder: (context, index) => Card(
                        key: ValueKey(_foundUsers[index]["id"]),
                        color: Colors.amberAccent,
                        elevation: 4,
                        margin: const EdgeInsets.symmetric(vertical: 10),
                        child: ListTile(
                          leading: Text(
                            _foundUsers[index]["id"].toString(),
                            style: const TextStyle(fontSize: 24),
                          ),
                          title: Text(_foundUsers[index]['name']),
                          subtitle: Text(
                              '${_foundUsers[index]["age"].toString()} years old'),
                        ),
                      ),
                    )
                  : const Text(
                      'No results found',
                      style: TextStyle(fontSize: 24),
                    ),
            ),
          ],
        ),
      ),
    );
  }
}

Actually, we don’t need a TextEditingController in this case.

Conclusion

You’ve learned how to create a filter/search ListView in Flutter. At this point, you should get a better understanding and become more comfortable when dealing with this task or something similar to it. Continue exploring list view and other interesting stuff by taking a look at the following articles:

You can also check out our Flutter topic page or Dart topic page for the latest tutorials and examples.

Subscribe
Notify of
guest
26 Comments
Inline Feedbacks
View all comments
Peter
Peter
7 months ago

Schön, aber wie integriere ich meine sqflite Datenbank?

usama malik
usama malik
11 months ago

how to add mysql database

Peter
Peter
7 months ago
Reply to  usama malik

Schön, aber wie integriere ich meine sqflite Datenbank?

Davoud
Davoud
1 year ago

Thanks

jony
jony
1 year ago

great

deviga devi
deviga devi
1 year ago

i want to add filter in tab bar view.how it is possible

mbrd
mbrd
1 year ago

hello,  Thanks for your tutorial, it’s great! I tried by creating a Map like: (word) – (translated word) and an option button to display the list either (word – translated word) or (translated word – word) but in the display (translated word – word) the result is no longer sorted… Read more »

Hoang Nguyen
Hoang Nguyen
1 year ago

Hi, Good Man: Flutter Hive CRUD should go one more step to include Search, making it CRUDS, which I have just done with your guide, and happy with it.

Hoang Nguyen
Hoang Nguyen
1 year ago

Great! Good Man. Thanks for your kindness.

siv
siv
1 year ago

source code please

first
first
2 years ago
  • fgg
rew
rew
2 years ago

How do we apply to Api

Bagas Galang Bijaky
Bagas Galang Bijaky
2 years ago

gracias

nova
nova
2 years ago

Sir, can I ask you this one question? Ummm is there any way that I can add the filter to this searching system?

Nursultan
Nursultan
2 years ago

Спасибо!

mahdi
mahdi
2 years ago

tank you bro

Ricardo
Ricardo
2 years ago

Genial..!!!

Ghina Sharaf
Ghina Sharaf
2 years ago

Thank you
you are the best <3

Klaus
Klaus
2 years ago

Thank you! I am a beginner and have looked for this example.

HHH
HHH
2 years ago

As always, thank you.

Related Articles