Kinda Code
Home/Flutter/How to Create a Sortable ListView in Flutter

How to Create a Sortable ListView in Flutter

Last updated: February 13, 2023

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:

You can also tour around our Flutter topic page or Dart topic page for the most recent tutorials and examples.