skip to Main Content

I’m trying to create a list of ingredients that can be re-ordered using Flutter/Dart. I’m using ReorderableListView and ReorderableDragStartListener. I can drag the items around, but they won’t re-ordered. They just snapped back to their original places. Any help? The data (ingredients) comes from an sqlite query (I’m using sqflite library).

This is the code that I have:

@override
Widget build(BuildContext context) {
  List<Map<String, dynamic>> ingredientsOrderable = List<Map<String, dynamic>>.from(ingredients);

  return Scaffold(
    body: SafeArea(
      child: ReorderableListView(
        onReorder: (int oldIndex, int newIndex) {
          setState(() {
            if (newIndex > oldIndex) {
              newIndex -= 1;
            }
            final ingredient = ingredientsOrderable.removeAt(oldIndex);
            ingredientsOrderable.insert(newIndex, ingredient);
          });
        },
        children: ingredientsOrderable.asMap().entries.map((entry) {
          final index = entry.key;
          final ingredient = entry.value;
          return ReorderableDragStartListener(
            index: index,
            key: Key(ingredient["ID"].toString()),
            child: ListTile(
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) =>
                        IngredientDetailPage(widget.db, ingredient["ID"]),
                  ),
                );
              },
              title: Text(ingredient["Name"]),
            ),
          );
        }).toList(),
      ),
    ),
  );
}

2

Answers


  1. Chosen as BEST ANSWER

    Nevermind. I forgot to copy the list back to the original. There are other things, but that's basically it.

        @override
        Widget build(BuildContext context) {
          List<Map<String, dynamic>> ingredientsOrderable = List<Map<String, dynamic>>.from(ingredients);
    
          return Scaffold(
            body: SafeArea(
              child: ReorderableListView(
                key: Key('reorderable_list'),
                onReorder: (int oldIndex, int newIndex) {
                  setState(() {
                    if (newIndex > oldIndex) {
                      newIndex -= 1;
                    }
                    final ingredient = ingredientsOrderable.removeAt(oldIndex);
                    ingredientsOrderable.insert(newIndex, ingredient);
                    ingredients = List<Map<String, dynamic>>.from(ingredientsOrderable);
                  });
                },
                children: ingredientsOrderable.asMap().entries.map((entry) {
                  final index = entry.key;
                  final ingredient = entry.value;
                  final key = Key(ingredient["ID"].toString());
    
                  return ListTile(
                    key: key,
                    onTap: () {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) =>
                              IngredientDetailPage(widget.db, ingredient["ID"]),
                        ),
                      );
                    },
                    title: Text(ingredient["Name"]),
                    leading: ReorderableDragStartListener(
                      index: index,
                      key: key,
                      child: Icon(Icons.drag_handle),
                    ),
                  );
                }).toList(),
              ),
            ),
          );
        }
    

  2. Your list needs to be in State not in build(). Every time your page refreshes (which it must, when you reorder) you are reinitializing the list to the original order. Doh!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search