In this article we'll be looking at how to use ReorderableListView
to reorder list items inside of our Flutter applications. The ReorderableListView
is part of the Material
library and should be used for smaller list(s) without a substantial amount of items.
The ReorderableListView
doesn't support the use of a builder
method as it uses a SingleChildScrollView
under the hood. As a result, you could see performance issue(s) with larger lists - keep this in mind!
Video
Prefer to watch a video? Here's one I recorded for this article:
Project Setup
The project we'll be creating is a simple "Top 10" list where the user can rank a list of items. Here's an example of it in action:
We'll start by creating a new Flutter project in the terminal:
# New Flutter project
$ flutter create fl_reorderable
# Open in editor
$ cd fl_reorderable && code .
Creating our Top Ten List
Firstly, we'll start off by creating a new Stateful Widget
named TopTenList
at lib/top_ten_list.dart
:
import 'package:flutter/material.dart';
class TopTenList extends StatefulWidget {
@override
_TopTenListState createState() => _TopTenListState();
}
class _TopTenListState extends State<TopTenList> {
List<String> topTenGames = [
"World of Warcraft",
"Final Fantasy VII",
"Animal Crossing",
"Diablo II",
"Overwatch",
"Valorant",
"Minecraft",
"Dota 2",
"Half Life 3",
"Grand Theft Auto: Vice City"
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Top Ten"),
),
body: ReorderableListView(
onReorder: (int oldIndex, int newIndex) {},
children: getListItems(),
),
);
}
List<ListTile> getListItems() => topTenGames
.asMap()
.map((i, item) => MapEntry(i, buildTenableListTile(item, i)))
.values
.toList();
ListTile buildTenableListTile(String item, int index) {
return ListTile(
key: ValueKey(item),
title: Text(item),
leading: Text("#${index + 1}"),
);
}
}
We've established a List<String>
which contains our topTenGames
(i.e. the data we'll be using to generate our _reorderableListItems
). This'll likely be a more complex model on your end, but a String
should suffice for our demo.
Go ahead and add the TopTenList
Widget to your main.dart
file:
import 'package:fl_reorderable/top_ten_list.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ReorderableListView',
theme: ThemeData(
brightness: Brightness.dark,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
debugShowCheckedModeBanner: false,
home: TopTenList(),
);
}
}
Reordering Items
You'll be able to initiate the reorder functionality on our TopTenList
by holding down (long press tapping) an item within the list. If you attempt to move this either above or below, it won't work and will snap back to its original position.
This is because we haven't implemented the onReorder
function. Let's do exactly that!
Add the onReorder
function below and update the ReorderableListView
to use this:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Top Ten"),
),
body: ReorderableListView(
onReorder: onReorder,
children: getListItems(),
),
);
}
void onReorder(int oldIndex, int newIndex) {
if (newIndex > oldIndex) {
newIndex -= 1;
}
setState(() {
String game = topTenGames[oldIndex];
topTenGames.removeAt(oldIndex);
topTenGames.insert(newIndex, game);
});
}
This now allows us to directly compare the state of the list depending on whether the user ordered it above or below the current item.
Why does this matter?
Note that if [oldIndex] is before [newIndex], removing the item at [oldIndex] from the list will reduce the list's length by one.
Implementations used by [ReorderableListView] will need to account for this when inserting before [newIndex].
We're then able to remove the item at the oldIndex
and replace this with the newIndex
, and as we're using setState
we're able to trigger a rebuild of the UI. This'll call our getListItems()
once more, rendering our new list and surrounding rankings.
Summary
This completes our Top Ten List! We've now got a list that we're able to reorder and display the current ranking. Some possible improvements to this could be:
- Give the user an option to create multiple lists with items per list
- Allow users to add, remove and edit items in the list
-
Persist list items to
localstorage
orshared_preferences
What would you like to see next? I'd love to hear your feedback at https://twitter.com/paulhalliday_io!
Code for this article: https://github.com/PaulHalliday/flutter_top_ten_list
Top comments (0)