Flutter flatter:sqflite没有显示列表

Flutter flatter:sqflite没有显示列表,flutter,sqflite,Flutter,Sqflite,我遵循这一点来练习sqflite,但是当我添加一个新变量时,它就不再起作用了。我正在添加String\u image,我为使用变量的位置添加了代码,但是当我运行代码时,它会运行,但添加功能不起作用(即,当我单击浮动按钮时,它会显示添加页面,但当我单击保存时,它不会显示更新的列表) 我们将非常感谢您的帮助 这是注释。省道: class Note { int _id; String _title; String _description; String _date

我遵循这一点来练习
sqflite
,但是当我添加一个新变量时,它就不再起作用了。我正在添加
String\u image
,我为使用变量的位置添加了代码,但是当我运行代码时,它会运行,但添加功能不起作用(即,当我单击浮动按钮时,它会显示添加页面,但当我单击
保存
时,它不会显示更新的列表)

我们将非常感谢您的帮助

这是
注释。省道


class Note {

    int _id;
    String _title;
    String _description;
    String _date;
    int _priority;
    String _image;

    Note(this._title, this._date, this._image, this._priority, [this._description]);

    Note.withId(this._id, this._title, this._date, this._image, this._priority, [this._description]);

    int get id => _id;

    String get title => _title;

    String get description => _description;

    int get priority => _priority;

    String get date => _date;

    String get image => _image;

    set title(String newTitle) {
        if (newTitle.length <= 255) {
            this._title = newTitle;
        }
    }

    set description(String newDescription) {
        if (newDescription.length <= 255) {
            this._description = newDescription;
        }
    }

    set priority(int newPriority) {
        if (newPriority >= 1 && newPriority <= 2) {
            this._priority = newPriority;
        }
    }

    set date(String newDate) {
        this._date = newDate;
    }

    set image(String newImage) {
        this._image = newImage;
    }


    // Convert a Note object into a Map object
    Map<String, dynamic> toMap() {

        var map = Map<String, dynamic>();
        if (id != null) {
            map['id'] = _id;
        }
        map['title'] = _title;
        map['description'] = _description;
        map['priority'] = _priority;
        map['date'] = _date;
        map['image'] = _image;

        return map;
    }

    // Extract a Note object from a Map object
    Note.fromMapObject(Map<String, dynamic> map) {
        this._id = map['id'];
        this._title = map['title'];
        this._description = map['description'];
        this._priority = map['priority'];
        this._date = map['date'];
        this._image = map['image'];
    }
}

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_app/models/note.dart';
import 'package:flutter_app/utils/database_helper.dart';
import 'package:intl/intl.dart';

class NoteDetail extends StatefulWidget {

    final String appBarTitle;
    final Note note;

    NoteDetail(this. note, this.appBarTitle);

    @override
  State<StatefulWidget> createState() {

    return NoteDetailState(this.note, this.appBarTitle);
  }
}

class NoteDetailState extends State<NoteDetail> {

    static var _priorities = ['High', 'Low'];

    DatabaseHelper helper = DatabaseHelper();

    String appBarTitle;
    Note note;

    TextEditingController titleController = TextEditingController();
    TextEditingController descriptionController = TextEditingController();

    NoteDetailState(this.note, this.appBarTitle);

    @override
  Widget build(BuildContext context) {

        TextStyle textStyle = Theme.of(context).textTheme.title;

        titleController.text = note.title;
        descriptionController.text = note.description;

    return WillPopScope(

        onWillPop: () {
            // Write some code to control things, when user press Back navigation button in device navigationBar
            moveToLastScreen();
        },

        child: Scaffold(
        appBar: AppBar(
            title: Text(appBarTitle),
            leading: IconButton(icon: Icon(
                    Icons.arrow_back),
                    onPressed: () {
                    // Write some code to control things, when user press back button in AppBar
                    moveToLastScreen();
                    }
            ),
        ),

        body: Padding(
            padding: EdgeInsets.only(top: 15.0, left: 10.0, right: 10.0),
            child: ListView(
                children: <Widget>[

                    // First element
                    ListTile(
                        title: DropdownButton(
                                items: _priorities.map((String dropDownStringItem) {
                                    return DropdownMenuItem<String> (
                                        value: dropDownStringItem,
                                        child: Text(dropDownStringItem),
                                    );
                                }).toList(),

                                style: textStyle,

                                value: getPriorityAsString(note.priority),

                                onChanged: (valueSelectedByUser) {
                                    setState(() {
                                      debugPrint('User selected $valueSelectedByUser');
                                      updatePriorityAsInt(valueSelectedByUser);
                                    });
                                }
                        ),
                    ),

                    // Second Element
                    Padding(
                        padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
                        child: TextField(
                            controller: titleController,
                            style: textStyle,
                            onChanged: (value) {
                                debugPrint('Something changed in Title Text Field');
                                updateTitle();
                            },
                            decoration: InputDecoration(
                                labelText: 'Title',
                                labelStyle: textStyle,
                                border: OutlineInputBorder(
                                    borderRadius: BorderRadius.circular(5.0)
                                )
                            ),
                        ),
                    ),

                    // Third Element
                    Padding(
                        padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
                        child: TextField(
                            controller: descriptionController,
                            style: textStyle,
                            onChanged: (value) {
                                debugPrint('Something changed in Description Text Field');
                                updateDescription();
                            },
                            decoration: InputDecoration(
                                    labelText: 'Description',
                                    labelStyle: textStyle,
                                    border: OutlineInputBorder(
                                            borderRadius: BorderRadius.circular(5.0)
                                    )
                            ),
                        ),
                    ),

                    // Fourth Element
                    Padding(
                        padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
                        child: Row(
                            children: <Widget>[
                                Expanded(
                                    child: RaisedButton(
                                        color: Theme.of(context).primaryColorDark,
                                        textColor: Theme.of(context).primaryColorLight,
                                        child: Text(
                                            'Save',
                                            textScaleFactor: 1.5,
                                        ),
                                        onPressed: () {
                                            setState(() {
                                              debugPrint("Save button clicked");
                                              _save();
                                            });
                                        },
                                    ),
                                ),

                                Container(width: 5.0,),

                                Expanded(
                                    child: RaisedButton(
                                        color: Theme.of(context).primaryColorDark,
                                        textColor: Theme.of(context).primaryColorLight,
                                        child: Text(
                                            'Delete',
                                            textScaleFactor: 1.5,
                                        ),
                                        onPressed: () {
                                            setState(() {
                                                debugPrint("Delete button clicked");
                                                _delete();
                                            });
                                        },
                                    ),
                                ),

                            ],
                        ),
                    ),

                ],
            ),
        ),

    ));
  }

  void moveToLastScreen() {
        Navigator.pop(context, true);
  }

    // Convert the String priority in the form of integer before saving it to Database
    void updatePriorityAsInt(String value) {
        switch (value) {
            case 'High':
                note.priority = 1;
                break;
            case 'Low':
                note.priority = 2;
                break;
        }
    }

    // Convert int priority to String priority and display it to user in DropDown
    String getPriorityAsString(int value) {
        String priority;
        switch (value) {
            case 1:
                priority = _priorities[0];  // 'High'
                break;
            case 2:
                priority = _priorities[1];  // 'Low'
                break;
        }
        return priority;
    }

    // Update the title of Note object
  void updateTitle(){
    note.title = titleController.text;
  }

    // Update the description of Note object
    void updateDescription() {
        note.description = descriptionController.text;
    }

    // Save data to database
    void _save() async {

        moveToLastScreen();
        note.image = "123"; //FIXME: Replace with the right image
        note.date = DateFormat.yMMMd().format(DateTime.now());
        int result;
        if (note.id != null) {  // Case 1: Update operation
            result = await helper.updateNote(note);
        } else { // Case 2: Insert Operation
            result = await helper.insertNote(note);
        }

        if (result != 0) {  // Success
            _showAlertDialog('Status', 'Note Saved Successfully');
        } else {  // Failure
            _showAlertDialog('Status', 'Problem Saving Note');
        }

    }

    void _delete() async {

        moveToLastScreen();

        // Case 1: If user is trying to delete the NEW NOTE i.e. he has come to
        // the detail page by pressing the FAB of NoteList page.
        if (note.id == null) {
            _showAlertDialog('Status', 'No Note was deleted');
            return;
        }

        // Case 2: User is trying to delete the old note that already has a valid ID.
        int result = await helper.deleteNote(note.id);
        if (result != 0) {
            _showAlertDialog('Status', 'Note Deleted Successfully');
        } else {
            _showAlertDialog('Status', 'Error Occured while Deleting Note');
        }
    }

    void _showAlertDialog(String title, String message) {

        AlertDialog alertDialog = AlertDialog(
            title: Text(title),
            content: Text(message),
        );
        showDialog(
                context: context,
                builder: (_) => alertDialog
        );
    }

}
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_app/models/note.dart';
import 'package:flutter_app/utils/database_helper.dart';
import 'package:flutter_app/screens/note_detail.dart';
import 'package:sqflite/sqflite.dart';


class NoteList extends StatefulWidget {

    @override
  State<StatefulWidget> createState() {

    return NoteListState();
  }
}

class NoteListState extends State<NoteList> {

    DatabaseHelper databaseHelper = DatabaseHelper();
    List<Note> noteList;
    int count = 0;

    @override
  Widget build(BuildContext context) {

        if (noteList == null) {
            noteList = List<Note>();
            updateListView();
        }

    return Scaffold(

        appBar: AppBar(
            title: Text('Notes'),
        ),

        body: getNoteListView(),

        floatingActionButton: FloatingActionButton(
            onPressed: () {
              debugPrint('FAB clicked');
              navigateToDetail(Note('', '', '', 2,), 'Add Note');
            },

            tooltip: 'Add Note',

            child: Icon(Icons.add),

        ),
    );
  }

  ListView getNoteListView() {

        TextStyle titleStyle = Theme.of(context).textTheme.subhead;

        return ListView.builder(
            itemCount: count,
            itemBuilder: (BuildContext context, int position) {
                return Card(
                    color: Colors.white,
                    elevation: 2.0,
                    child: ListTile(

                        leading: CircleAvatar(
                            backgroundColor: getPriorityColor(this.noteList[position].priority),
                            child: getPriorityIcon(this.noteList[position].priority),
                        ),

                        title: Text(this.noteList[position].title, style: titleStyle,),

                        subtitle: Text(this.noteList[position].date),

                        trailing: GestureDetector(
                            child: Icon(Icons.delete, color: Colors.grey,),
                            onTap: () {
                                _delete(context, noteList[position]);
                            },
                        ),


                        onTap: () {
                            debugPrint("ListTile Tapped");
                            navigateToDetail(this.noteList[position],'Edit Note');
                        },

                    ),
                );
            },
        );
  }

  // Returns the priority color
    Color getPriorityColor(int priority) {
        switch (priority) {
            case 1:
                return Colors.red;
                break;
            case 2:
                return Colors.yellow;
                break;

            default:
                return Colors.yellow;
        }
    }

    // Returns the priority icon
    Icon getPriorityIcon(int priority) {
        switch (priority) {
            case 1:
                return Icon(Icons.play_arrow);
                break;
            case 2:
                return Icon(Icons.keyboard_arrow_right);
                break;

            default:
                return Icon(Icons.keyboard_arrow_right);
        }
    }

    void _delete(BuildContext context, Note note) async {

        int result = await databaseHelper.deleteNote(note.id);
        if (result != 0) {
            _showSnackBar(context, 'Note Deleted Successfully');
            updateListView();
        }
    }

    void _showSnackBar(BuildContext context, String message) {

        final snackBar = SnackBar(content: Text(message));
        Scaffold.of(context).showSnackBar(snackBar);
    }

  void navigateToDetail(Note note, String title) async {
      bool result = await Navigator.push(context, MaterialPageRoute(builder: (context) {
          return NoteDetail(note, title);
      }));

      if (result == true) {
        updateListView();
      }
  }

  void updateListView() {

        final Future<Database> dbFuture = databaseHelper.initializeDatabase();
        dbFuture.then((database) {

            Future<List<Note>> noteListFuture = databaseHelper.getNoteList();
            noteListFuture.then((noteList) {
                setState(() {
                  this.noteList = noteList;
                  this.count = noteList.length;
                });
            });
        });
  }
}

import 'package:sqflite/sqflite.dart';
import 'dart:async';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_app/models/note.dart';

class DatabaseHelper {

    static DatabaseHelper _databaseHelper;    // Singleton DatabaseHelper
    static Database _database;                // Singleton Database

    String noteTable = 'note_table';
    String colId = 'id';
    String colTitle = 'title';
    String colDescription = 'description';
    String colPriority = 'priority';
    String colDate = 'date';
    String colImage = 'image';

    DatabaseHelper._createInstance(); // Named constructor to create instance of DatabaseHelper

    factory DatabaseHelper() {

        if (_databaseHelper == null) {
            _databaseHelper = DatabaseHelper._createInstance(); // This is executed only once, singleton object
        }
        return _databaseHelper;
    }

    Future<Database> get database async {

        if (_database == null) {
            _database = await initializeDatabase();
        }
        return _database;
    }

    Future<Database> initializeDatabase() async {
        // Get the directory path for both Android and iOS to store database.
        Directory directory = await getApplicationDocumentsDirectory();
        String path = directory.path + 'notes.db';

        // Open/create the database at a given path
        var notesDatabase = await openDatabase(path, version: 1, onCreate: _createDb);
        return notesDatabase;
    }

    void _createDb(Database db, int newVersion) async {

        await db.execute('CREATE TABLE $noteTable($colId INTEGER PRIMARY KEY AUTOINCREMENT, $colTitle TEXT, '
                '$colDescription TEXT, $colPriority INTEGER, $colDate TEXT, $colImage TEXT)');
    }

    // Fetch Operation: Get all note objects from database
    Future<List<Map<String, dynamic>>> getNoteMapList() async {
        Database db = await this.database;

//      var result = await db.rawQuery('SELECT * FROM $noteTable order by $colPriority ASC');
        var result = await db.query(noteTable, orderBy: '$colPriority ASC');
        return result;
    }

    // Insert Operation: Insert a Note object to database
    Future<int> insertNote(Note note) async {
        Database db = await this.database;
        var result = await db.insert(noteTable, note.toMap());
        return result;
    }

    // Update Operation: Update a Note object and save it to database
    Future<int> updateNote(Note note) async {
        var db = await this.database;
        var result = await db.update(noteTable, note.toMap(), where: '$colId = ?', whereArgs: [note.id]);
        return result;
    }

    // Delete Operation: Delete a Note object from database
    Future<int> deleteNote(int id) async {
        var db = await this.database;
        int result = await db.rawDelete('DELETE FROM $noteTable WHERE $colId = $id');
        return result;
    }

    // Get number of Note objects in database
    Future<int> getCount() async {
        Database db = await this.database;
        List<Map<String, dynamic>> x = await db.rawQuery('SELECT COUNT (*) from $noteTable');
        int result = Sqflite.firstIntValue(x);
        return result;
    }

    // Get the 'Map List' [ List<Map> ] and convert it to 'Note List' [ List<Note> ]
    Future<List<Note>> getNoteList() async {

        var noteMapList = await getNoteMapList(); // Get 'Map List' from database
        int count = noteMapList.length;         // Count the number of map entries in db table

        List<Note> noteList = List<Note>();
        // For loop to create a 'Note List' from a 'Map List'
        for (int i = 0; i < count; i++) {
            noteList.add(Note.fromMapObject(noteMapList[i]));
        }

        return noteList;
    }

}

这是注释列表。省道


class Note {

    int _id;
    String _title;
    String _description;
    String _date;
    int _priority;
    String _image;

    Note(this._title, this._date, this._image, this._priority, [this._description]);

    Note.withId(this._id, this._title, this._date, this._image, this._priority, [this._description]);

    int get id => _id;

    String get title => _title;

    String get description => _description;

    int get priority => _priority;

    String get date => _date;

    String get image => _image;

    set title(String newTitle) {
        if (newTitle.length <= 255) {
            this._title = newTitle;
        }
    }

    set description(String newDescription) {
        if (newDescription.length <= 255) {
            this._description = newDescription;
        }
    }

    set priority(int newPriority) {
        if (newPriority >= 1 && newPriority <= 2) {
            this._priority = newPriority;
        }
    }

    set date(String newDate) {
        this._date = newDate;
    }

    set image(String newImage) {
        this._image = newImage;
    }


    // Convert a Note object into a Map object
    Map<String, dynamic> toMap() {

        var map = Map<String, dynamic>();
        if (id != null) {
            map['id'] = _id;
        }
        map['title'] = _title;
        map['description'] = _description;
        map['priority'] = _priority;
        map['date'] = _date;
        map['image'] = _image;

        return map;
    }

    // Extract a Note object from a Map object
    Note.fromMapObject(Map<String, dynamic> map) {
        this._id = map['id'];
        this._title = map['title'];
        this._description = map['description'];
        this._priority = map['priority'];
        this._date = map['date'];
        this._image = map['image'];
    }
}

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_app/models/note.dart';
import 'package:flutter_app/utils/database_helper.dart';
import 'package:intl/intl.dart';

class NoteDetail extends StatefulWidget {

    final String appBarTitle;
    final Note note;

    NoteDetail(this. note, this.appBarTitle);

    @override
  State<StatefulWidget> createState() {

    return NoteDetailState(this.note, this.appBarTitle);
  }
}

class NoteDetailState extends State<NoteDetail> {

    static var _priorities = ['High', 'Low'];

    DatabaseHelper helper = DatabaseHelper();

    String appBarTitle;
    Note note;

    TextEditingController titleController = TextEditingController();
    TextEditingController descriptionController = TextEditingController();

    NoteDetailState(this.note, this.appBarTitle);

    @override
  Widget build(BuildContext context) {

        TextStyle textStyle = Theme.of(context).textTheme.title;

        titleController.text = note.title;
        descriptionController.text = note.description;

    return WillPopScope(

        onWillPop: () {
            // Write some code to control things, when user press Back navigation button in device navigationBar
            moveToLastScreen();
        },

        child: Scaffold(
        appBar: AppBar(
            title: Text(appBarTitle),
            leading: IconButton(icon: Icon(
                    Icons.arrow_back),
                    onPressed: () {
                    // Write some code to control things, when user press back button in AppBar
                    moveToLastScreen();
                    }
            ),
        ),

        body: Padding(
            padding: EdgeInsets.only(top: 15.0, left: 10.0, right: 10.0),
            child: ListView(
                children: <Widget>[

                    // First element
                    ListTile(
                        title: DropdownButton(
                                items: _priorities.map((String dropDownStringItem) {
                                    return DropdownMenuItem<String> (
                                        value: dropDownStringItem,
                                        child: Text(dropDownStringItem),
                                    );
                                }).toList(),

                                style: textStyle,

                                value: getPriorityAsString(note.priority),

                                onChanged: (valueSelectedByUser) {
                                    setState(() {
                                      debugPrint('User selected $valueSelectedByUser');
                                      updatePriorityAsInt(valueSelectedByUser);
                                    });
                                }
                        ),
                    ),

                    // Second Element
                    Padding(
                        padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
                        child: TextField(
                            controller: titleController,
                            style: textStyle,
                            onChanged: (value) {
                                debugPrint('Something changed in Title Text Field');
                                updateTitle();
                            },
                            decoration: InputDecoration(
                                labelText: 'Title',
                                labelStyle: textStyle,
                                border: OutlineInputBorder(
                                    borderRadius: BorderRadius.circular(5.0)
                                )
                            ),
                        ),
                    ),

                    // Third Element
                    Padding(
                        padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
                        child: TextField(
                            controller: descriptionController,
                            style: textStyle,
                            onChanged: (value) {
                                debugPrint('Something changed in Description Text Field');
                                updateDescription();
                            },
                            decoration: InputDecoration(
                                    labelText: 'Description',
                                    labelStyle: textStyle,
                                    border: OutlineInputBorder(
                                            borderRadius: BorderRadius.circular(5.0)
                                    )
                            ),
                        ),
                    ),

                    // Fourth Element
                    Padding(
                        padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
                        child: Row(
                            children: <Widget>[
                                Expanded(
                                    child: RaisedButton(
                                        color: Theme.of(context).primaryColorDark,
                                        textColor: Theme.of(context).primaryColorLight,
                                        child: Text(
                                            'Save',
                                            textScaleFactor: 1.5,
                                        ),
                                        onPressed: () {
                                            setState(() {
                                              debugPrint("Save button clicked");
                                              _save();
                                            });
                                        },
                                    ),
                                ),

                                Container(width: 5.0,),

                                Expanded(
                                    child: RaisedButton(
                                        color: Theme.of(context).primaryColorDark,
                                        textColor: Theme.of(context).primaryColorLight,
                                        child: Text(
                                            'Delete',
                                            textScaleFactor: 1.5,
                                        ),
                                        onPressed: () {
                                            setState(() {
                                                debugPrint("Delete button clicked");
                                                _delete();
                                            });
                                        },
                                    ),
                                ),

                            ],
                        ),
                    ),

                ],
            ),
        ),

    ));
  }

  void moveToLastScreen() {
        Navigator.pop(context, true);
  }

    // Convert the String priority in the form of integer before saving it to Database
    void updatePriorityAsInt(String value) {
        switch (value) {
            case 'High':
                note.priority = 1;
                break;
            case 'Low':
                note.priority = 2;
                break;
        }
    }

    // Convert int priority to String priority and display it to user in DropDown
    String getPriorityAsString(int value) {
        String priority;
        switch (value) {
            case 1:
                priority = _priorities[0];  // 'High'
                break;
            case 2:
                priority = _priorities[1];  // 'Low'
                break;
        }
        return priority;
    }

    // Update the title of Note object
  void updateTitle(){
    note.title = titleController.text;
  }

    // Update the description of Note object
    void updateDescription() {
        note.description = descriptionController.text;
    }

    // Save data to database
    void _save() async {

        moveToLastScreen();
        note.image = "123"; //FIXME: Replace with the right image
        note.date = DateFormat.yMMMd().format(DateTime.now());
        int result;
        if (note.id != null) {  // Case 1: Update operation
            result = await helper.updateNote(note);
        } else { // Case 2: Insert Operation
            result = await helper.insertNote(note);
        }

        if (result != 0) {  // Success
            _showAlertDialog('Status', 'Note Saved Successfully');
        } else {  // Failure
            _showAlertDialog('Status', 'Problem Saving Note');
        }

    }

    void _delete() async {

        moveToLastScreen();

        // Case 1: If user is trying to delete the NEW NOTE i.e. he has come to
        // the detail page by pressing the FAB of NoteList page.
        if (note.id == null) {
            _showAlertDialog('Status', 'No Note was deleted');
            return;
        }

        // Case 2: User is trying to delete the old note that already has a valid ID.
        int result = await helper.deleteNote(note.id);
        if (result != 0) {
            _showAlertDialog('Status', 'Note Deleted Successfully');
        } else {
            _showAlertDialog('Status', 'Error Occured while Deleting Note');
        }
    }

    void _showAlertDialog(String title, String message) {

        AlertDialog alertDialog = AlertDialog(
            title: Text(title),
            content: Text(message),
        );
        showDialog(
                context: context,
                builder: (_) => alertDialog
        );
    }

}
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_app/models/note.dart';
import 'package:flutter_app/utils/database_helper.dart';
import 'package:flutter_app/screens/note_detail.dart';
import 'package:sqflite/sqflite.dart';


class NoteList extends StatefulWidget {

    @override
  State<StatefulWidget> createState() {

    return NoteListState();
  }
}

class NoteListState extends State<NoteList> {

    DatabaseHelper databaseHelper = DatabaseHelper();
    List<Note> noteList;
    int count = 0;

    @override
  Widget build(BuildContext context) {

        if (noteList == null) {
            noteList = List<Note>();
            updateListView();
        }

    return Scaffold(

        appBar: AppBar(
            title: Text('Notes'),
        ),

        body: getNoteListView(),

        floatingActionButton: FloatingActionButton(
            onPressed: () {
              debugPrint('FAB clicked');
              navigateToDetail(Note('', '', '', 2,), 'Add Note');
            },

            tooltip: 'Add Note',

            child: Icon(Icons.add),

        ),
    );
  }

  ListView getNoteListView() {

        TextStyle titleStyle = Theme.of(context).textTheme.subhead;

        return ListView.builder(
            itemCount: count,
            itemBuilder: (BuildContext context, int position) {
                return Card(
                    color: Colors.white,
                    elevation: 2.0,
                    child: ListTile(

                        leading: CircleAvatar(
                            backgroundColor: getPriorityColor(this.noteList[position].priority),
                            child: getPriorityIcon(this.noteList[position].priority),
                        ),

                        title: Text(this.noteList[position].title, style: titleStyle,),

                        subtitle: Text(this.noteList[position].date),

                        trailing: GestureDetector(
                            child: Icon(Icons.delete, color: Colors.grey,),
                            onTap: () {
                                _delete(context, noteList[position]);
                            },
                        ),


                        onTap: () {
                            debugPrint("ListTile Tapped");
                            navigateToDetail(this.noteList[position],'Edit Note');
                        },

                    ),
                );
            },
        );
  }

  // Returns the priority color
    Color getPriorityColor(int priority) {
        switch (priority) {
            case 1:
                return Colors.red;
                break;
            case 2:
                return Colors.yellow;
                break;

            default:
                return Colors.yellow;
        }
    }

    // Returns the priority icon
    Icon getPriorityIcon(int priority) {
        switch (priority) {
            case 1:
                return Icon(Icons.play_arrow);
                break;
            case 2:
                return Icon(Icons.keyboard_arrow_right);
                break;

            default:
                return Icon(Icons.keyboard_arrow_right);
        }
    }

    void _delete(BuildContext context, Note note) async {

        int result = await databaseHelper.deleteNote(note.id);
        if (result != 0) {
            _showSnackBar(context, 'Note Deleted Successfully');
            updateListView();
        }
    }

    void _showSnackBar(BuildContext context, String message) {

        final snackBar = SnackBar(content: Text(message));
        Scaffold.of(context).showSnackBar(snackBar);
    }

  void navigateToDetail(Note note, String title) async {
      bool result = await Navigator.push(context, MaterialPageRoute(builder: (context) {
          return NoteDetail(note, title);
      }));

      if (result == true) {
        updateListView();
      }
  }

  void updateListView() {

        final Future<Database> dbFuture = databaseHelper.initializeDatabase();
        dbFuture.then((database) {

            Future<List<Note>> noteListFuture = databaseHelper.getNoteList();
            noteListFuture.then((noteList) {
                setState(() {
                  this.noteList = noteList;
                  this.count = noteList.length;
                });
            });
        });
  }
}

import 'package:sqflite/sqflite.dart';
import 'dart:async';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_app/models/note.dart';

class DatabaseHelper {

    static DatabaseHelper _databaseHelper;    // Singleton DatabaseHelper
    static Database _database;                // Singleton Database

    String noteTable = 'note_table';
    String colId = 'id';
    String colTitle = 'title';
    String colDescription = 'description';
    String colPriority = 'priority';
    String colDate = 'date';
    String colImage = 'image';

    DatabaseHelper._createInstance(); // Named constructor to create instance of DatabaseHelper

    factory DatabaseHelper() {

        if (_databaseHelper == null) {
            _databaseHelper = DatabaseHelper._createInstance(); // This is executed only once, singleton object
        }
        return _databaseHelper;
    }

    Future<Database> get database async {

        if (_database == null) {
            _database = await initializeDatabase();
        }
        return _database;
    }

    Future<Database> initializeDatabase() async {
        // Get the directory path for both Android and iOS to store database.
        Directory directory = await getApplicationDocumentsDirectory();
        String path = directory.path + 'notes.db';

        // Open/create the database at a given path
        var notesDatabase = await openDatabase(path, version: 1, onCreate: _createDb);
        return notesDatabase;
    }

    void _createDb(Database db, int newVersion) async {

        await db.execute('CREATE TABLE $noteTable($colId INTEGER PRIMARY KEY AUTOINCREMENT, $colTitle TEXT, '
                '$colDescription TEXT, $colPriority INTEGER, $colDate TEXT, $colImage TEXT)');
    }

    // Fetch Operation: Get all note objects from database
    Future<List<Map<String, dynamic>>> getNoteMapList() async {
        Database db = await this.database;

//      var result = await db.rawQuery('SELECT * FROM $noteTable order by $colPriority ASC');
        var result = await db.query(noteTable, orderBy: '$colPriority ASC');
        return result;
    }

    // Insert Operation: Insert a Note object to database
    Future<int> insertNote(Note note) async {
        Database db = await this.database;
        var result = await db.insert(noteTable, note.toMap());
        return result;
    }

    // Update Operation: Update a Note object and save it to database
    Future<int> updateNote(Note note) async {
        var db = await this.database;
        var result = await db.update(noteTable, note.toMap(), where: '$colId = ?', whereArgs: [note.id]);
        return result;
    }

    // Delete Operation: Delete a Note object from database
    Future<int> deleteNote(int id) async {
        var db = await this.database;
        int result = await db.rawDelete('DELETE FROM $noteTable WHERE $colId = $id');
        return result;
    }

    // Get number of Note objects in database
    Future<int> getCount() async {
        Database db = await this.database;
        List<Map<String, dynamic>> x = await db.rawQuery('SELECT COUNT (*) from $noteTable');
        int result = Sqflite.firstIntValue(x);
        return result;
    }

    // Get the 'Map List' [ List<Map> ] and convert it to 'Note List' [ List<Note> ]
    Future<List<Note>> getNoteList() async {

        var noteMapList = await getNoteMapList(); // Get 'Map List' from database
        int count = noteMapList.length;         // Count the number of map entries in db table

        List<Note> noteList = List<Note>();
        // For loop to create a 'Note List' from a 'Map List'
        for (int i = 0; i < count; i++) {
            noteList.add(Note.fromMapObject(noteMapList[i]));
        }

        return noteList;
    }

}