Previously we discussed best practices for Flutter slide deletion on listViews. Now let’s look at ListView drag sorting.

The effect is as follows:


To achieve the above effect, you need to use this class.

A list whose items the user can interactively reorder by dragging.

This class is appropriate for views with a small number of children because constructing the List requires doing work for every child that could possibly be displayed in the list view instead of just those children that are actually visible.

All children must have a key.

A simple translation is as follows:

The user can drag to reorder the list.

This class is good for pages with a small number of children, because constructing the list requires an operation for each child, not just the visible children.

All children must have a key.

The constructor

As a convention, look at the constructor:

  @required this.children,
  @required this.onReorder,
  this.scrollDirection = Axis.vertical,
  this.reverse = false,}) :assert(scrollDirection ! =null),
assert(onReorder ! =null),
assert(children ! =null),
assert( children.every((Widget w) => w.key ! =null),
  'All children of this widget must have a key.',);Copy the code

Take a look at the parameters:

  • Header: is a Widget that does not participate in drag sorting
  • Children: Needless to say, list items
  • OnReorder: by definition, reordered callback
  • ScrollDirection: the direction

I won’t go into the other two, but I should know both of them.

Simple to use

Now that we have seen the constructor, we can write a Demo in a minute:

class _ReorderableListViewPageState extends State<ReorderableListViewPage> {
  List<Color> _data = [,

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ReorderableListViewPage'),
      body: ReorderableListView(
          header: Container(
            height: 50,
          children: _data
              .map((s) => Card(
                    color: s,
                    key: Key(s.toString()),
                    child: Container(
                      width: 300,
                      height: 100,
          onReorder: (int oldIndex, int newIndex) {
            print("$oldIndex --- $newIndex"); })); }}Copy the code
  1. First we define a list of colors
  2. Then return it in the build methodReorderableListView
  3. ReorderableListViewChildren in is defined by colorCard
  4. inonReorderTwo arguments are printed in the callbackoldIndex & newIndex

Run it and look at the printed log:

You can see that it does print out the old and the new indexes, but there’s an obvious problem here,

We all know that the index of an array starts at 0, and you can see that the first one is 0 to 3, the second one is 0 to 4,

But reasoning should be zero to two, zero to three.

So why did MY newIndex +1 after the first two moves?

We’re not going to go into that here,

If we’re going to move, we’re going to do something to the source data, or the move is fake.

So, based on such a newIndex, all we need is this:

setState(() {
  if(oldIndex < newIndex) {
  	newIndex -= 1;	

  var temp = _data.removeAt(oldIndex);
  _data.insert(newIndex, temp);
Copy the code
  1. Decide whether to drag it up or down
  2. If you drag it down, you’re going to have one more newIndex, so let’s subtract that
  3. Then we delete the old data and save it
  4. Finally, insert into the new index

ListView drag-and-drop sort and delete

Delete ListView delete ListView delete ListView delete ListView delete

The code was simple, and enabled by the fact that Flutter was a Widget. We simply wrapped a Dismissible missible Card around Flutter:

children: _data
  .map((s) => Dismissible(
    key: Key("dismiss $s"),
    child: Card(
      color: s,
      key: Key(s.toString()),
      child: Container(
        width: 300,
        height: 100,
Copy the code


In Flutter, we can encapsulate many widgets to save time for future development,

Of course, don’t forget the Widget tests in Flutter