/Lista_de_Tarefas

import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.dart'; void main() { runApp(MaterialApp( home: Home(), )); } class Home extends StatefulWidget { const Home({Key key}) : super(key: key); @override _HomeState createState() => _HomeState(); } class _HomeState extends State<Home> { final _ToDoController = TextEditingController(); List _toDoList = []; Map<String,dynamic> _lastRemoved; int _lastRemovedPos; @override void initState(){ super.initState(); _readData().then((data){ setState(() { _toDoList= json.decode(data); }); }); } // armazenar cada tarefa (dynamic) void _addToDo(){ setState(() { Map<String, dynamic> newToDo = Map(); newToDo["title"]= _ToDoController.text; _ToDoController.text = ""; newToDo["Ok"] = false; _toDoList.add(newToDo); _savedata(); }); } Future<Null> _refresh() async{ await Future.delayed(Duration(seconds: 1)); setState(() { _toDoList.sort((a, p){ if(a["Ok"] && !p["Ok"]) return 1; else if (!a["Ok"] && p["Ok"]) return -1; else return 0; }); _savedata(); }); return null; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text ("Lista de Tarefas"), backgroundColor: Colors.lightBlueAccent, centerTitle: true, ), body: Column( children: <Widget>[ Container( padding: EdgeInsets.fromLTRB(17.0, 1.0, 7.0, 1.0), child: Row ( children:<Widget> [ Expanded(child: TextField( controller: _ToDoController, decoration: InputDecoration( labelText: "Nova Tarefa", labelStyle: TextStyle(color: Colors.lightBlueAccent) ), ), ), RaisedButton( color: Colors.lightBlueAccent, child: Text("ADD"), textColor: Colors.white, onPressed: _addToDo, ) ], ), ), //Criando a Lista Expanded(child: RefreshIndicator(onRefresh: _refresh, child: ListView.builder( padding: EdgeInsets.only(top: 10.0), itemCount: _toDoList.length, itemBuilder: buildItem ), ) ), ]), ); } // criando as tarefas Widget buildItem (context,index){ // criando um botão que da para clicar ou marcar return Dismissible( key: Key(DateTime.now().microsecondsSinceEpoch.toString()), background: Container( color: Colors.red, child: Align( alignment: Alignment(-0.9, 0.0 ), child: Icon(Icons.delete, color: Colors.white,), ), ), direction: DismissDirection.startToEnd , child: CheckboxListTile( title: Text (_toDoList[index]['title']), value: (_toDoList[index]['Ok']) , secondary: CircleAvatar( child: Icon(_toDoList[index]['Ok']? Icons.check: Icons.error), ), onChanged: (c){ setState(() { _toDoList[index]["Ok"]= c; _savedata(); }); }, ) , // duplicar o item que estou a tentar remover onDismissed: (direction){ setState(() { _lastRemoved= Map.from(_toDoList[index]); _lastRemovedPos = index; _toDoList.removeAt(index); _savedata(); final snack = SnackBar( content: Text("Tarefa " "\"${_lastRemoved["title"]}\" " "removida!"), action: SnackBarAction(label: "Desfazer", onPressed:(){ setState(() { _toDoList.insert(_lastRemovedPos, _lastRemoved); _savedata(); }); }), duration: Duration(seconds: 2), ); Scaffold.of(context).showSnackBar(snack); }); }, ); } Future<File> _getFile() async { final directory = await getApplicationDocumentsDirectory(); return File('${directory.path}/data.json'); } Future<File> _savedata() async { String data = json.encode(_toDoList); final file = await _getFile(); return file.writeAsString(data); } Future<String> _readData() async { try { final file =await _getFile(); return file.readAsString(); } catch(e) { return null; } } }

Lista_de_Tarefas

import 'dart:convert'; import 'dart:io';

import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.dart';

void main() { runApp(MaterialApp( home: Home(), )); } class Home extends StatefulWidget { const Home({Key key}) : super(key: key);

@override _HomeState createState() => _HomeState(); }

class _HomeState extends State { final _ToDoController = TextEditingController();

List _toDoList = [];

Map<String,dynamic> _lastRemoved; int _lastRemovedPos;

@override void initState(){ super.initState();

_readData().then((data){
  setState(() {
    _toDoList= json.decode(data);
  });


});

}

// armazenar cada tarefa (dynamic) void _addToDo(){ setState(() { Map<String, dynamic> newToDo = Map(); newToDo["title"]= _ToDoController.text; _ToDoController.text = ""; newToDo["Ok"] = false; _toDoList.add(newToDo);

_savedata();

}); }

Future _refresh() async{ await Future.delayed(Duration(seconds: 1));

setState(() { _toDoList.sort((a, p){ if(a["Ok"] && !p["Ok"]) return 1; else if (!a["Ok"] && p["Ok"]) return -1; else return 0; });

_savedata();

}); return null; }

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text ("Lista de Tarefas"), backgroundColor: Colors.lightBlueAccent, centerTitle: true,

  ),
  body: Column(
    children: <Widget>[
      Container(
        padding:  EdgeInsets.fromLTRB(17.0, 1.0, 7.0, 1.0),
        child:  Row (
          children:<Widget> [
           Expanded(child:
           TextField(
             controller: _ToDoController,
             decoration: InputDecoration(
                 labelText: "Nova Tarefa",
                 labelStyle: TextStyle(color: Colors.lightBlueAccent)
             ),
           ),
             ),
            RaisedButton(
              color: Colors.lightBlueAccent,
              child: Text("ADD"),
              textColor: Colors.white,
              onPressed: _addToDo,
            )
          ],
        ),
      ),
   //Criando a Lista
     Expanded(child:
         RefreshIndicator(onRefresh: _refresh,
       child: ListView.builder(
padding: EdgeInsets.only(top: 10.0),
itemCount: _toDoList.length,
itemBuilder:
buildItem
),
      )
  ),
]),
);

} // criando as tarefas Widget buildItem (context,index){ // criando um botão que da para clicar ou marcar return Dismissible( key: Key(DateTime.now().microsecondsSinceEpoch.toString()), background: Container( color: Colors.red, child: Align( alignment: Alignment(-0.9, 0.0 ), child: Icon(Icons.delete, color: Colors.white,), ), ), direction: DismissDirection.startToEnd , child: CheckboxListTile( title: Text (_toDoList[index]['title']), value: (_toDoList[index]['Ok']) , secondary: CircleAvatar( child: Icon(_toDoList[index]['Ok']? Icons.check: Icons.error), ), onChanged: (c){ setState(() { _toDoList[index]["Ok"]= c; _savedata(); }); },

  ) ,
 // duplicar o item que estou a tentar remover
  onDismissed: (direction){
   setState(() {
     _lastRemoved= Map.from(_toDoList[index]);
     _lastRemovedPos = index;
     _toDoList.removeAt(index);

     _savedata();
     
     final snack =
     SnackBar(
       content:
       Text("Tarefa "
           "\"${_lastRemoved["title"]}\" "
           "removida!"),
           action: SnackBarAction(label: "Desfazer",
         onPressed:(){
             setState(() {

               _toDoList.insert(_lastRemovedPos, _lastRemoved);
               _savedata();
             });
     }),
       duration: Duration(seconds: 2),
     );
     
     Scaffold.of(context).showSnackBar(snack);
   });

  },
);

}

Future _getFile() async { final directory = await getApplicationDocumentsDirectory(); return File('${directory.path}/data.json');

}

Future _savedata() async { String data = json.encode(_toDoList); final file = await _getFile(); return file.writeAsString(data); } Future _readData() async { try { final file =await _getFile();

  return file.readAsString();

} catch(e) {
  return null;

}
}

}