flutterdartsqflitereorderable-list

Flutter Reorderable List going back to it's original state


I made the list reorderable but now it's going back to its initial state. Can someone help me? My list consists of List Tile which is generated from the database using Asynsnapshot. The key I used is the same as the index. It seems like the insert function isn't inserting the note in the new index. Is it because the future builder is rebuilding?

body: Container(
          padding: EdgeInsets.all(8.0),
          child: ListView(
            children: <Widget>[
              SizedBox(
                  height: MediaQuery.of(context).size.height * 0.882,
                  child: FutureBuilder(
                      future: databaseHelper.getNoteList(),
                      builder: (BuildContext context, AsyncSnapshot snapshot) {
                        if (snapshot.data == null) {
                          return Text('Loading');
                        } else {
                          if (snapshot.data.length < 1) {
                            return Center(
                              child: Text('No Messages, Create New one'),
                            );
                          }
                          return ReorderableListView(
                            children: List.generate(
                              snapshot.data.length,
                              (index) {
                                return ListTile(
                                  key: Key('$index'),
                                  title: Text(
                                    snapshot.data[index].title,
                                    style: TextStyle(
                                      fontWeight: FontWeight.bold,
                                      fontSize: 20,
                                    ),
                                  ),
                                  subtitle: Text(snapshot.data[index].note,
                                      maxLines: 4),
                                  trailing: InkWell(
                                    child: Icon(Icons.add_box,
                                        color: Colors.green),
                                    onTap: () {
                                      TextEditingController txt =
                                          TextEditingController();

                                      txt.text = snapshot.data[index].note;
                                      print(txt);
                                      Route route = MaterialPageRoute(
                                          builder: (context) =>
                                              MyHomePage(custMessage: txt));
                                      Navigator.push(context, route);
                                      // addNewMessageDialog(txt);
                                    },
                                  ),
                                  // isThreeLine: true,
                                  onTap: () {
                                    Route route = MaterialPageRoute(
                                        builder: (context) => AddNote(
                                              note: snapshot.data[index],
                                            ));
                                    Navigator.push(context, route);
                                  },
                                );
                              },
                            ).toList(),
                            onReorder: _onReorder,
                          );
                        }
                      }))
            ],
          )),

Reoder function

void _onReorder(int oldIndex, int newIndex) async {
    var snapshot = await databaseHelper.getNoteList();

    if (newIndex > snapshot.length) newIndex = snapshot.length;
    if (oldIndex < newIndex) newIndex -= 1;
   
      setState(() {
        final Note item = snapshot[oldIndex];
        snapshot.removeAt(oldIndex);

        print(item.title);
        snapshot.insert(newIndex, item);
      });
   
  }

I tried adding future delay but no use. enter image description here enter image description hereenter image description here enter image description here


Solution

  • You can copy paste run full code below
    You do not need to call databaseHelper.getNoteList() in _onReorder again
    You can use noteList = snapshot.data; and operate noteList

    code snippet

    void _onReorder(int oldIndex, int newIndex) async {
        if (newIndex > noteList.length) newIndex = noteList.length;
        if (oldIndex < newIndex) newIndex -= 1;
    
        setState(() {
          final Note item = noteList[oldIndex];
          noteList.removeAt(oldIndex);
    
          print(item.title);
          noteList.insert(newIndex, item);
        });
      }
    ...
    noteList = snapshot.data;
          return ReorderableListView(
    

    working demo

    enter image description here

    full code

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class Note {
      String title;
      String note;
    
      Note({this.title, this.note});
    }
    
    class databaseHelper {
      static Future<List<Note>> getNoteList() {
        return Future.value([
          Note(title: "1", note: "n1"),
          Note(title: "2", note: "n2"),
          Note(title: "3", note: "n3"),
          Note(title: "4", note: "n4"),
          Note(title: "5", note: "n5")
        ]);
      }
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      List<Note> noteList = [];
      Future<List<Note>> _future;
    
      void _onReorder(int oldIndex, int newIndex) async {
        if (newIndex > noteList.length) newIndex = noteList.length;
        if (oldIndex < newIndex) newIndex -= 1;
    
        setState(() {
          final Note item = noteList[oldIndex];
          noteList.removeAt(oldIndex);
    
          print(item.title);
          noteList.insert(newIndex, item);
        });
      }
    
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        _future = databaseHelper.getNoteList();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Container(
              padding: EdgeInsets.all(8.0),
              child: ListView(
                children: <Widget>[
                  SizedBox(
                      height: MediaQuery.of(context).size.height * 0.882,
                      child: FutureBuilder(
                          future: _future,
                          builder: (BuildContext context, AsyncSnapshot snapshot) {
                            if (snapshot.data == null) {
                              return Text('Loading');
                            } else {
                              if (snapshot.data.length < 1) {
                                return Center(
                                  child: Text('No Messages, Create New one'),
                                );
                              }
    
                              noteList = snapshot.data;
                              return ReorderableListView(
                                children: List.generate(
                                  snapshot.data.length,
                                  (index) {
                                    return ListTile(
                                      key: Key('$index'),
                                      title: Text(
                                        snapshot.data[index].title,
                                        style: TextStyle(
                                          fontWeight: FontWeight.bold,
                                          fontSize: 20,
                                        ),
                                      ),
                                      subtitle: Text(snapshot.data[index].note,
                                          maxLines: 4),
                                      trailing: InkWell(
                                        child: Icon(Icons.add_box,
                                            color: Colors.green),
                                        onTap: () {
                                          /*TextEditingController txt =
                                          TextEditingController();
    
                                          txt.text = snapshot.data[index].note;
                                          print(txt);
                                          Route route = MaterialPageRoute(
                                              builder: (context) =>
                                                  MyHomePage(custMessage: txt));
                                          Navigator.push(context, route);*/
                                          // addNewMessageDialog(txt);
                                        },
                                      ),
                                      // isThreeLine: true,
                                      onTap: () {
                                        /*Route route = MaterialPageRoute(
                                            builder: (context) => AddNote(
                                              note: snapshot.data[index],
                                            ));
                                        Navigator.push(context, route);*/
                                      },
                                    );
                                  },
                                ).toList(),
                                onReorder: _onReorder,
                              );
                            }
                          }))
                ],
              )),
        );
      }
    }