Building a Persistent Reorderable List in Flutter: A Step-by-Step Guide

Abdusalam Abubakar Olajide
Stackademic
Published in
3 min readOct 13, 2023

--

Photo by Arnold Francisca on Unsplash

Following the previous tutorial on Building a Reorderable List in Flutter: A Step-by-Step Guide

Welcome to the second part of our tutorial series on creating a persistent reordering experience in your Flutter app. In the first part, you learned how to implement a dynamic reorderable list that allows users to arrange items with drag-and-drop ease. Now, let’s explore the realm of persistence and ensure that the art of reordering doesn’t just thrive for a moment but stands strong across time and interactions.

In this part, we’ll focus on leveraging Flutter’s SharedPreferences to store and restore the order of your reordered list. No longer will users lose their customized arrangements when the app restarts or data undergoes changes.

Are you excited to unlock the power of persistence? Let’s dive right in and ensure that your users’ reordering efforts remain an enduring part of their app experience!

In our journey towards keeping your list in order, let’s welcome a new player: the keys variable. This simple addition will help us maintain the custom list arrangement, ensuring it stays put even when things change.

List<String> keys = [];

Our next move involves the orderKeys method. This method captures the keys from our initial data obtained through getData. Which in this case its id.

List<String> get orderKeys =>
listOfData.map((e) => e['id'].toString()).toList();

Then we create a function to save the keys of our new list.

Future<void> saveOrders(List<String> keys) async {
final pref = await SharedPreferences.getInstance();
await pref.setStringList('order_key', keys);
}

Now we refactor our onReorder method to use the keys and save them after reordering.

void onReorder(oldIndex, newIndex) {
if (newIndex > oldIndex) newIndex--;

keys.insert(newIndex, keys.removeAt(oldIndex));

saveOrders(keys);

setState(() {});
}

We use below function to get our saved order.

Future<void> getSavedOrders() async {
final pref = await SharedPreferences.getInstance();
final localOrders = pref.getStringList('order_key');

if (localOrders == null || localOrders.isEmpty) {
keys = orderKeys;

return;
}

keys = localOrders;
}

This returns the original keys if the local returns empty.

Now let’s introduce getOrderData function. This function serves as your data retriever, a tool that helps you showcase the right information while looping through your list of keys.

Here’s how it works:

  • You provide a key to the getOrderData function, which represents an item's unique identifier.
  • The function scans through your original list of data, seeking the item that matches the provided key.
  • If a match is found, it returns that data, allowing you to display the correct information.
  • If no match is found, the function gracefully defaults to a placeholder map with preset values.

By using getOrderData, you're ensuring that each key is associated with its corresponding data, making your displayed information accurate and contextually relevant.

Here’s the getOrderData function in action:

Map getOrderData(String key) {
final defaultMap = {'id': '0', 'name': 'Option 0', 'done': false};

return listOfData.firstWhere(
(data) => data['id'] == key,
orElse: () => defaultMap,
);
}

We then refactor our widget to use the keys variable and getOrderData function:

 @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Persistent Reorderable List'),
),
body: Center(
child: ReorderableListView(
onReorder: onReorder,
children: keys.map((key) {
final data = getOrderData(key);

return Card(
key: ValueKey(data['id']),
child: ListTile(
title: Text(data['name']),
trailing: const Icon(Icons.arrow_forward_ios),
),
);
}).toList(),
),
),
);
}

Stackademic

Thank you for reading until the end. Before you go:

  • Please consider clapping and following the writer! 👏
  • Follow us on Twitter(X), LinkedIn, and YouTube.
  • Visit Stackademic.com to find out more about how we are democratizing free programming education around the world.

--

--