0

I am working on a simple Todolist app. I have created a database to store the data under the file "to_do_item.dart". the file "database_helper.dart" is where i have stored all the CRUD functions.

When the app is opened, the user will see a screen created under the file "todo_list.dart" where the added tasks will be displayed in a listview. when the user clicks the action button, it will send them to "input_screen.dart" where there is a textfield to enter the tasks. after the user clicks "done" on the on-screen keyboard, the data will be saved in a list called "Itemlist" (line 49 of "input_screen").

I want to send this list to "todo_list.dart" and display them in a scrollable listview but i am unsure of what method to use. At the moment i am only trying to add the item and display it.

Tried using getters but was unable to use it for another class, and tried searching how other todolist apps on flutter were made but they use an AlertDialog on the same class; i want to take input from one screen(class InputScreen) and display it on another screen (class TodoList).

CODE UNDER "todo_list.dart" -

      Container(
              color: Colors.white,
              alignment: Alignment.topLeft,
              margin: const EdgeInsets.all(20),
              child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    SizedBox(height: 110,),
                    Text( "tasks for today",),
                    SizedBox(height: 20,),

                    //Todo: display listview on below column 

//                   Column(
//                     children: <Widget>[
//                       new Flexible(child: ListView.builder(
itemBuilder:(_,intindex){
//                       return ListTile(
////                         title: _itema,
//                       );
//                       }
//                       )
//                       )
//                     ],
//                   ),

                    SizedBox(height: 320,),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.end,
                      children: <Widget>[
                        FloatingActionButton(
                          onPressed: (){
                            Navigator.push(context, MaterialPageRoute(builder: (context) => InputScreen()));
                          },
                          heroTag: "btn2",
                          child: Icon(Icons.add, color: Colors.white,), backgroundColor: Colors.black87,),
                      ],
                    )
                  ]
              ),
            ),

CODE UNDER "input_screen.dart"

    class InputScreen extends StatefulWidget {
  @override
  _InputScreenState createState() => _InputScreenState();
}

class _InputScreenState extends State<InputScreen> {


  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _readList();

  }    

  void _handleSubmitted(String text) async{
    taskcontroller.clear();
    TodoItem obj = new TodoItem(text, DateTime.now().toIso8601String());
    int SavedItemId = await db.saveItem(obj);
    print("item saved id: $SavedItemId");
    print("$text");
    TodoItem addedItem = await db.getItem(SavedItemId);
    setState(() {
      Itemlist.insert(0, addedItem);
    });
  }

  _readList() async{
    List items = await db.getItems();
    items.forEach((item) {
      TodoItem todoItem = TodoItem.map(items);
      print("db it4ems: ${todoItem.itemName.toString()}");
    });
  }    

  var db = new DatabaseHelper();    

  final List<TodoItem> Itemlist= <TodoItem>[];
  TextEditingController taskcontroller = new TextEditingController();
  @override
  Widget build(BuildContext context) {
    SystemChrome.setEnabledSystemUIOverlays([]);
    return Scaffold(
      resizeToAvoidBottomPadding: false,
      backgroundColor: Colors.white,
      body: SingleChildScrollView(

        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
//       crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Container(
              color: Colors.white,
              alignment: Alignment.topLeft,
              margin: const EdgeInsets.all(20),
              child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    SizedBox(height: 110,),
                    Text("tasks for today:",),
                    SizedBox(height: 10,),

                    //Todo: remove sized box below and display tasks there
                    TextField(
                      autofocus: true,
                      onEditingComplete: (){Navigator.pop(context);},
                      maxLength: 10,
                      onSubmitted: (NewValue){ _handleSubmitted(NewValue);},
                      controller: taskcontroller,
                      decoration: InputDecoration(
                        labelText: "enter tasks here"
                      ),
                      style: TextStyle(height: 1.2, fontSize: 20, color: Colors.black87),

                    )
                  ]
              ),
            ),
          ],
        ),
      ),
    );
  }
}

CODE UNDER "to_do_item.dart" -

    import 'package:flutter/material.dart';

class TodoItem extends StatelessWidget {
  String _itemName;
  String _dateCreated;
  int _id;    

  TodoItem(this._itemName, this._dateCreated);

  TodoItem.map(dynamic obj) {
    this._itemName = obj["itemName"];
    this._dateCreated = obj["dateCreated"];
    this._id = obj["id"];
  }

  String get itemName => _itemName;
  String get dateCreated => _dateCreated;
  int get id => _id;

  Map<String, dynamic> toMap() {
    var map = new Map<String, dynamic>();
    map["itemName"] = _itemName;
    map["dateCreated"] = _dateCreated;

    if (_id != null) {
      map["id"] = _id;
    }

    return map;
  }

  TodoItem.fromMap(Map<String, dynamic> map) {
    this._itemName = map["itemName"];
    this._dateCreated = map["dateCreated"];
    this._id = map["id"];    
  }    

  @override
  Widget build(BuildContext context) {
    return new Container(
      margin: const EdgeInsets.all(8.0),
      child: new Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          new Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Text(_itemName, )
            ],
          ),
        ],
      ),
    );
  }
}

CODE UNDER "database_helper.dart" -

    import 'dart:io';

import 'to_do_item.dart';
import 'package:path/path.dart';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';

class DatabaseHelper {
  static final DatabaseHelper _instance = new DatabaseHelper.internal();

  factory DatabaseHelper() => _instance;

  final String tableName = "todotbl";
  final String columnId = "id";
  final String columnItemName = "itemName";
  final String columnDateCreated = "dateCreated";

  static Database _db;

  Future<Database> get db async {
    if (_db != null) {
      return _db;
    }
    _db = await initDb();
    return _db;
  }

  DatabaseHelper.internal();

  initDb() async {
    Directory documentDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentDirectory.path, "todolist_db.db");
    var ourDb = await openDatabase(path, version: 1, onCreate: _onCreate);
    return ourDb;
  }

  void _onCreate(Database db, int version) async {
    await db.execute(
        "CREATE TABLE $tableName(id INTEGER PRIMARY KEY, $columnItemName TEXT, $columnDateCreated TEXT)");
    print("Table is created");
  }

//insertion
  Future<int> saveItem(TodoItem item) async {
    var dbClient = await db;
    int res = await dbClient.insert("$tableName", item.toMap());
    print(res.toString());
    return res;
  }

  //Get
  Future<List> getItems() async {
    var dbClient = await db;
    var result = await dbClient.rawQuery(
        "SELECT * FROM $tableName ORDER BY $columnItemName ASC"); //ASC

    return result.toList();

//    if (result.length == 0) return [];
//    var users = [];
//
//    for (Map<String, dynamic> map in result) {
//       users.add(new User.fromMap(map));
//    }
//
//    return users;

  }

  Future<int> getCount() async {
    var dbClient = await db;
    return Sqflite.firstIntValue(await dbClient.rawQuery(
        "SELECT COUNT(*) FROM $tableName"
    ));
  }

//
  Future<TodoItem> getItem(int id) async {
    var dbClient = await db;
    var result = await dbClient.rawQuery(
        "SELECT * FROM $tableName WHERE id = $id");
    if (result.length == 0) return null;
    return new TodoItem.fromMap(result.first);
  }

  //deletion
//  Future<int> deleteItem(int id) async {
//    var dbClient = await db;
//    var result = await dbClient.rawQuery("DELETE FROM $tableName WHERE id = $id");
//    if (result.length == 0) return null;
//    return result.first as int;
//  }

  Future<int> deleteItem(int id) async {
    var dbClient = await db;
    return await dbClient.delete(tableName,
        where: "$columnId = ?", whereArgs: [id]);
  }

  Future<int> updateItem(TodoItem item) async {
    var dbClient = await db;
    return await dbClient.update("$tableName", item.toMap(),
        where: "$columnId = ?", whereArgs: [item.id]);
  }

  Future close() async {
    var dbClient = await db;
    return dbClient.close();
  }
}
Nipun Tharuksha
  • 2,496
  • 4
  • 17
  • 40

1 Answers1

0

This is possibly a duplicate of this

Nonetheless I hope this helps

class FrontPage extends StatefulWidget {
  @override
  _FrontPageState createState() => _FrontPageState();
}

class _FrontPageState extends State<FrontPage> {

//  Activity currentActivity;
  var recentActivities = <Widget>[];//<Widget>[Activity("Skiing", "assets/activity_logos/Squat.png").getSummary(),Activity("Skiing", "assets/activity_logos/Squat.png").getSummary(),Activity("Skiing", "assets/activity_logos/Squat.png").getSummary(),Activity("Skiing", "assets/activity_logos/Squat.png").getSummary(),Activity("Skiing", "assets/activity_logos/Squat.png").getSummary(),Activity("Skiing", "assets/activity_logos/Squat.png").getSummary()];
  var upcomingActivities = <Widget>[];//<Widget>[Activity("Jog", "assets/activity_logos/Squat.png", status: ActivityStatus.completed,).getSummary()];

  List<String> tasks = ["previous1", "previous2"];

  @override
  Widget build(BuildContext context) {
    return  Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text('Home'),
        actions: <Widget>[
          GestureDetector(
            child: Align(child:Text("+", style: TextStyle(fontSize: 40)), alignment: Alignment.centerLeft, widthFactor: 2,),
            onTap: () => Navigator.pushNamed(context, '/activity/new'),
          )
        ],
      ),
      body: Container(
        color: Colors.white,
        alignment: Alignment.topLeft,
        margin: const EdgeInsets.all(20),
        child: Stack(
            alignment: Alignment.bottomRight,
            children: <Widget>[
              Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    SizedBox(height: 110,),
                    Text( "tasks for today",),
                    SizedBox(height: 20,),
                    Expanded(child: ListView.builder(
                        itemCount: tasks.length,
                        itemBuilder: (BuildContext context, int index) {
                          return Text(tasks[index]);
                        })),
                  ]),
                  FloatingActionButton(
                    onPressed: () async {
                      final result = await Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => InputScreen(),
                          ));
                      setState(() {
                        tasks.add(result);
                      });
                    },
                    heroTag: "btn2",
                    child: Icon(Icons.add, color: Colors.white,), backgroundColor: Colors.black87,),
            ]),
      ),
    );
  }
}

class InputScreen extends StatefulWidget {
  @override
  _InputScreenState createState() => _InputScreenState();
}

class _InputScreenState extends State<InputScreen> {

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
//    _readList();

  }

//  final List<TodoItem> Itemlist= <TodoItem>[];
  TextEditingController taskcontroller = new TextEditingController();
  @override
  Widget build(BuildContext context) {
    SystemChrome.setEnabledSystemUIOverlays([]);
    return Scaffold(
      resizeToAvoidBottomPadding: false,
      backgroundColor: Colors.white,
      body: SingleChildScrollView(

        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
//       crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Container(
              color: Colors.white,
              alignment: Alignment.topLeft,
              margin: const EdgeInsets.all(20),
              child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    SizedBox(height: 110,),
                    Text("tasks for today:",),
                    SizedBox(height: 10,),

                    //Todo: remove sized box below and display tasks there
                    TextField(
                      autofocus: true,
                      onEditingComplete: () {
                        String textToSendBack = taskcontroller.text;
                        Navigator.pop(context, textToSendBack );
                      },
                      maxLength: 10,
                      onSubmitted: (NewValue){  },
                      controller: taskcontroller,
                      decoration: InputDecoration(
                          labelText: "enter tasks here"
                      ),
                      style: TextStyle(height: 1.2, fontSize: 20, color: Colors.black87),

                    )
                  ]
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class TodoItem extends StatelessWidget {
  String _itemName;
  String _dateCreated;
  int _id;


  TodoItem(this._itemName, this._dateCreated);

  TodoItem.map(dynamic obj) {
    this._itemName = obj["itemName"];
    this._dateCreated = obj["dateCreated"];
    this._id = obj["id"];
  }

  String get itemName => _itemName;
  String get dateCreated => _dateCreated;
  int get id => _id;

  Map<String, dynamic> toMap() {
    var map = new Map<String, dynamic>();
    map["itemName"] = _itemName;
    map["dateCreated"] = _dateCreated;

    if (_id != null) {
      map["id"] = _id;
    }

    return map;
  }

  TodoItem.fromMap(Map<String, dynamic> map) {
    this._itemName = map["itemName"];
    this._dateCreated = map["dateCreated"];
    this._id = map["id"];

  }


  @override
  Widget build(BuildContext context) {
    return new Container(
      margin: const EdgeInsets.all(8.0),
      child: new Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          new Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Text(_itemName, )
            ],
          ),
        ],
      ),
    );
  }
}

The main changes consist of

On input page:

TextField(
   autofocus: true,
   onEditingComplete: () {
       String textToSendBack = taskcontroller.text;
       Navigator.pop(context, textToSendBack );
   }

On the front page:

 FloatingActionButton(
      onPressed: () async {
        final result = await Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => InputScreen(),
            ));
        setState(() {
          tasks.add(result);
        });
      },

Some widgeting layout, and I am keeping the data in a tasks array but you can change as you wish.

Durdu
  • 4,649
  • 2
  • 27
  • 47