Table of Contents
Introduction
When developing Flutter apps, in some cases, we may want to provide the option for the user to sort the items in the ListView based on specific criteria. This sortable ListView provides a user-friendly way to view and sort the data in the app, making it easier and faster for them to find the information they need.
This practical article walks you through a complete example of making a sortable ListView in Flutter. We’ll write code from scratch without using any third-party packages.
The Example
App Preview
The demo app we’re going to make has a ListView that displays a list of fiction products with 3 attributes: id, name, and price. The user can sort the products in the ListView by price (low to high, high to low) by tapping the Price label in the header of the ListView. The header will also show an up or down arrow icon indicating whether the products are sorted in ascending or descending order.
Here’s how it works:
The Code
Here’s the complete code in main.dart (with explanations in the comments):
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.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({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// the sort order
// true: ascending, false: descending
bool _sortAscending = true;
// the list of products
final List<Map<String, dynamic>> _products = [
{'id': 1, 'name': 'Dragon Robot', 'price': 19.99},
{'id': 2, 'name': 'Turtle Toy', 'price': 15.99},
{'id': 3, 'name': 'White Board', 'price': 12.99},
{'id': 4, 'name': 'KindaCode.com', 'price': 24.99},
{'id': 5, 'name': 'Travel Bag', 'price': 17.99},
];
// the function that sorts the list of products
// this function is called when the user taps the sort button
void _sortProducts(bool ascending) {
setState(() {
_sortAscending = ascending;
_products.sort((a, b) => ascending
? a['price'].compareTo(b['price'])
: b['price'].compareTo(a['price']));
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('KindaCode.com'),
),
body: Column(
children: [
// The header of the list
Container(
padding: const EdgeInsets.symmetric(vertical: 29, horizontal: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
_sortAscending ? 'Price Low to High' : 'Price High to Low',
style: const TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
// the sort button
InkWell(
onTap: () => _sortProducts(!_sortAscending),
child: Row(
children: [
const Text(
'Price',
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
// the up/down arrow that indicates the sort order
Icon(
_sortAscending
? Icons.arrow_drop_down
: Icons.arrow_drop_up,
color: Colors.blue,
),
],
),
),
],
),
),
// The list of products
Expanded(
child: ListView.builder(
itemCount: _products.length,
itemBuilder: (context, index) {
// the list item - product
return Container(
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.only(bottom: 3),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(5.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${_products[index]['id']}',
style: const TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
),
),
Text(
'${_products[index]['name']}',
style: const TextStyle(
fontSize: 16.0,
),
),
Text(
'\$${_products[index]['price']}',
style: const TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.green,
),
),
],
),
);
},
),
),
],
),
);
}
}
Alternative: Example of sortable DataTable in Flutter (with explanations).
Conclusion
Congratulations! You’ve done it, a decent sortable ListView. Although the logic here is not too complicated, it works well in most cases. So, in the future, if you find it necessary to implement a sortable ListView, you won’t need to change much code compared to the example above.
If you’d like to explore more new and fascinating things in the world of modern Flutter, take a look at the following articles:
- Flutter: 2 Ways to Create an Onboarding Flow (Intro Slider)
- Working with the Align widget in Flutter
- 2 Ways to Get a Random Item from a List in Dart (and Flutter)
- Flutter AnimatedList – Tutorial and Examples
- Flutter SliverList – Tutorial and Example
- Flutter & Hive Database: CRUD Example
You can also tour around our Flutter topic page or Dart topic page for the most recent tutorials and examples.