How to rearrange list in flutter

In our previous section we’ve seen how we can rearrange list in Flutter. Yes, we are talking off ReorderableListView widget. By the way, we can also rearrange list in flutter using ReorderableListView.builder constructor.

The ReorderableListView.builder constructor creates a reorderable list from widget items that are created on demand. In a different way ReorderableListView also allows us to build a reorderable list with all the items that we pass into the constructor.

The ReorderableListView widget is good for small number of items. On the contrary, we can use ReorderableListView.builder constructor for list views with a large number of children.

Because ReorderableListView.builder constructor performs in a different way, we can handle a large number of list view.

To understand that, let us see all the parameters of ReorderableListView.builder constructor.

const ReorderableListView.builder(
{Key? key,
required IndexedWidgetBuilder itemBuilder,
required int itemCount,
required ReorderCallback onReorder,
double? itemExtent,
Widget? prototypeItem,
ReorderItemProxyDecorator? proxyDecorator,
bool buildDefaultDragHandles,
EdgeInsets? padding,
Widget? header,
Axis scrollDirection,
bool reverse,
ScrollController? scrollController,
bool? primary,
ScrollPhysics? physics,
bool shrinkWrap,
double anchor,
double? cacheExtent,
DragStartBehavior dragStartBehavior,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior,
String? restorationId,
Clip clipBehavior}
)

The above code snippet shows us the three parameters that are required.

One of them is itemBuilder callback that will be called only with indices greater than or equal to zero and less than another required parameter itemCount.

In addition, another required parameter is onReorder, which is a callback by the list, which reports that a list item has been dragged to a new position in the list. Certainly, the name fully justifies its significance.

We’ll realise that if we take a look at the following screenshot.

ReorderableListView second instance where item is being dragged
ReorderableListView second instance where item is being dragged

Because we’re dragging an item and placing it at a new location, we’re reordering the list.

To make more sense to our statement, let’s take a look at the full code snippet first. After that, we’ll discuss how it works.

import 'package:flutter/material.dart';

/// This is the main application widget.
class ReorderableListViewBuilderSample extends StatelessWidget {
  const ReorderableListViewBuilderSample({Key? key}) : super(key: key);

  static const String _title = 'ReorderableListView Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(title: const Text(_title)),
        body: const ReorderableListViewBuilderHome(),
      ),
    );
  }
}

/// This is the stateful widget that the main application instantiates.
class ReorderableListViewBuilderHome extends StatefulWidget {
  const ReorderableListViewBuilderHome({Key? key}) : super(key: key);

  @override
  State<ReorderableListViewBuilderHome> createState() =>
      _ReorderableListViewBuilderHomeState();
}

class _ReorderableListViewBuilderHomeState
    extends State<ReorderableListViewBuilderHome> {
  /// generating 10 items
  final List<int> _items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

  @override
  Widget build(BuildContext context) {
    return ReorderableListView.builder(
        itemCount: _items.length,
        itemBuilder: (context, index) {
          final String itemName = '${_items[index]}';
          return Container(
            key: ValueKey(itemName),
            decoration: BoxDecoration(
              color: Colors.blue,
              border: Border.all(
                color: Colors.red,
                width: 2.0,
                style: BorderStyle.solid,
              ),
              borderRadius: const BorderRadius.all(Radius.circular(40.0)),
              boxShadow: const [
                BoxShadow(
                  color: Colors.black54,
                  blurRadius: 20.0,
                  spreadRadius: 20.0,
                ),
              ],
              gradient: const LinearGradient(
                begin: Alignment.centerLeft,
                end: Alignment.centerRight,
                colors: [
                  Colors.red,
                  Colors.white,
                ],
              ),
            ),
            child: ListTile(
              contentPadding: const EdgeInsets.all(25),
              leading: const Icon(Icons.input_outlined),
              title: Text(
                itemName,
                key: ValueKey(itemName),
                style: const TextStyle(
                  color: Colors.black,
                  fontSize: 80.0,
                  fontFamily: 'Allison',
                  fontWeight: FontWeight.bold,
                ),
              ),
              trailing: const Icon(Icons.drag_indicator_outlined),
            ),
          );
        },
        // The reorder function
        onReorder: (oldIndex, newIndex) {
          setState(() {
            if (newIndex > oldIndex) {
              newIndex = newIndex - 1;
            }
            final element = _items.removeAt(oldIndex);
            _items.insert(newIndex, element);
          });
        });
  }
}

If we compare the above code with the previous code snippet of ReorderableListView, we’ll realise that this time we don’t have to map the list anymore. Moreover, the item Builder parameter creates the widget instances when called, returning a non-null widget.

It’s more efficient as long as performance is concerned. Why? Because it creates the instances on demand using constructor’s itemBuilder callback.

However, the reordering is arranged by our good old friend and one of the required parameters, onReorder.

onReorder: (oldIndex, newIndex) {
          setState(() {
            if (newIndex > oldIndex) {
              newIndex = newIndex - 1;
            }
            final element = _items.removeAt(oldIndex);
            _items.insert(newIndex, element);
          });
        }

Finally the ReorderableListView.builder constructor creates the list on demand by using the IndexedWidgetBuilder, so that the list items are built lazily on demand.

For more awesome and magical Flutter UI widgets you may visit this GitHub repository.

By the way, you may want to take a look at the other Scrolling Widgets, before we close down further reading on this topic. We have a list below.

What is ListView Flutter? How do I use ListView in Flutter?

How do I use SingleChildScrollView in flutter?

What is GridView and how do you centre a GridView item in Flutter?

What is GridView builder in Flutter?

What is the grid view in Flutter?

What is GridView count in flutter?

What is GridView.extent in Flutter?

How do I make my collapsing toolbar flutter?

What is SliverGrid in flutter?

How to use CustomScrollView in Flutter?

How to use NestedScrollView in flutter?

How to use PageView in Flutter

What is PageView builder in flutter?

What is PageView custom in flutter?

How to use DraggableScrollableSheet

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

GitHub repository

Technical blog

Twitter

Comments

One response to “How to rearrange list in flutter”

  1. […] We have used the double “type” to add the margin and padding. In one case we have used the Boolean. Subsequently, to build a Row, we have used the List. […]

Leave a Reply