ListView is an important component of a mobile application. Developers are most often use ListView for showing a list of data to the user. In Flutter making a ListView and searching data from ListView is really simple and easy to implement. If you are looking for a step-by-step tutorial on searching data from ListView with example code, you are in the right place. Here I'll show you how to make a search functionality with Flutter ListView.
We have to make a page by extending the StatefulWidget for making search functionality on Flutter ListView.
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
HomePageState createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
}
For this section, here I'll load a local JSON file from the assets folder for feeding data to my ListView. You can follow the post for reading local JSON data in Flutter. Here is the JSON file content in assets/persons.json
file.
[
{
"name": "Rodger",
"city": "Banqiao"
},
{
"name": "Peadar",
"city": "Boronów"
},
{
"name": "Deina",
"city": "Mönchengladbach"
},
{
"name": "Karisa",
"city": "Alanga"
},
{
"name": "Annecorinne",
"city": "Aoufous"
}
]
Make a loadData
method inside HomePageState
and call the method in initState
. Our loadData method will parse the JSON data from the file and store the data into two List variable.
import 'package:flutter/services.dart';
import 'dart:convert';
List persons = [];
List original = [];
void loadData() async {
String jsonStr = await rootBundle.loadString('assets/persons.json');
var json = jsonDecode(jsonStr);
persons = json;
original = json;
setState(() {});
}
@override
void initState() {
super.initState();
loadData();
}
Note: Here List original
list variable will be used when we'll make a search method for searching data from our ListView.
Make a separate _listView
private method to make our listview UI design more organized.
Widget _listView(persons) {
return Expanded(
child: ListView.builder(
itemCount: persons.length,
itemBuilder: (context, index) {
var person = persons[index];
return ListTile(
leading: CircleAvatar(
child: Text(person['name'][0]),
),
title: Text(person['name']),
subtitle: Text("City: " + person['city']),
);
}),
);
}
Now call it into page UI like _listView(persons)
where you want to show the ListView.
Add a TextEditingController
for clearing search query easily by clicking a suffix icon button.
TextEditingController txtQuery = new TextEditingController();
Add a TextFormField into UI.
TextFormField(
controller: txtQuery,
onChanged: search,
decoration: InputDecoration(
hintText: "Search",
border: OutlineInputBorder(borderRadius: BorderRadius.circular(4.0)),
focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black)),
prefixIcon: Icon(Icons.search),
suffixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: () {
txtQuery.text = '';
search(txtQuery.text);
},
),
),
),
We have added a TextFormField for searching data from ListView and called a search function with onChange property. Let's make the search method.
void search(String query) {
if (query.isEmpty) {
persons = original;
setState(() {});
return;
}
query = query.toLowerCase();
print(query);
List result = [];
persons.forEach((p) {
var name = p["name"].toString().toLowerCase();
if (name.contains(query)) {
result.add(p);
}
});
persons = result;
setState(() {});
}
Done! Our ListView will look like the UI given below.
Here is the complete code for the Flutter ListView search.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:convert';
class HomePage extends StatefulWidget {
HomePageState createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
List persons = [];
List original = [];
TextEditingController txtQuery = new TextEditingController();
void loadData() async {
String jsonStr = await rootBundle.loadString('assets/persons.json');
var json = jsonDecode(jsonStr);
persons = json;
original = json;
setState(() {});
}
void search(String query) {
if (query.isEmpty) {
persons = original;
setState(() {});
return;
}
query = query.toLowerCase();
print(query);
List result = [];
persons.forEach((p) {
var name = p["name"].toString().toLowerCase();
if (name.contains(query)) {
result.add(p);
}
});
persons = result;
setState(() {});
}
@override
void initState() {
super.initState();
loadData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter Tutorial"),
),
body: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text( "List view search", style: TextStyle(fontWeight: FontWeight.bold)),
SizedBox(height: 10),
TextFormField(
controller: txtQuery,
onChanged: search,
decoration: InputDecoration(
hintText: "Search",
border: OutlineInputBorder(borderRadius: BorderRadius.circular(4.0)),
focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black)),
prefixIcon: Icon(Icons.search),
suffixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: () {
txtQuery.text = '';
search(txtQuery.text);
},
),
),
),
],
),
),
_listView(persons)
]),
);
}
}
Widget _listView(persons) {
return Expanded(
child: ListView.builder(
itemCount: persons.length,
itemBuilder: (context, index) {
var person = persons[index];
return ListTile(
leading: CircleAvatar(
child: Text(person['name'][0]),
),
title: Text(person['name']),
subtitle: Text("City: " + person['city']),
);
}),
);
}
Hope this step by step tutorial for how to make search functionality in Flutter Listview will help you to implement the search functionality into your app. If you find this tutorial helpful then please share it with others.