본문으로 건너뛰기

Flutter SQFLite 튜토리얼 및 CRUD 예제

Flutter SQFlite 튜토리얼 및 예제

Flutter에서 SQLite 데이터베이스로 작업하는 방법.

Flutter가 무엇인가요?

Flutter는 기록적인 시간 내에 iOS 및 Android에서 고품질 기본 인터페이스를 제작하기 위한 Google의 모바일 앱 SDK입니다.

Flutter는 기존 코드와 함께 작동하고 전 세계 개발자와 조직에서 사용하며 무료이며 오픈 소스입니다.

Flutter의 세 가지 주요 기능은 다음과 같습니다.

1. 빠른 개발

Flutter는 hot Reload를 통해 밀리초 단위로 앱에 생기를 불어넣을 수 있습니다.

완전히 사용자 정의할 수 있는 풍부한 위젯 세트를 사용하여 기본 인터페이스를 몇 분 안에 구축할 수도 있습니다.

2. 표현력 있고 유연한 UI

Flutter를 사용하면 기본 최종 사용자 경험에 중점을 둔 기능을 빠르게 제공할 수 있습니다.

계층화된 아키텍처를 통해 완전한 사용자 정의가 가능하므로 매우 빠른 렌더링과 표현력이 풍부하고 유연한 디자인이 가능합니다.

삼. 기본 성능

Flutter의 위젯은 스크롤링, 탐색, 아이콘 및 글꼴과 같은 모든 중요한 플랫폼 차이점을 통합하여 iOS 및 [Android](/android/introduction.

SQFlite란?

SQflite는 Flutter용 플러그인입니다. Flutter 코드를 통해 SQLite 데이터베이스를 저장, 검색 및 조작할 수 있습니다. SQflite는 Android 및 iOS 플랫폼을 모두 지원합니다.

다음은 SQFlite의 일부 기능입니다.

  1. SQFlite는 데이터베이스 트랜잭션과 배치를 모두 제공합니다.
  2. SQlite에는 자동 버전 관리 기능이 내장되어 있습니다.
  3. SQFlite는 데이터베이스에서 데이터를 삽입, 쿼리, 업데이트 및 삭제하기 위한 사용하기 쉬운 방법을 제공합니다.
  4. 이러한 CRUD 작업은 iOS 및 Android의 백그라운드 스레드에서 수행됩니다. 이렇게 하면 UI가 응답성을 유지할 수 있습니다.

SQFlite 설치 방법

SQFlite 설치는 다른 Flutter 패키지만큼 쉽습니다. Dart Package Repository에서 호스팅되며 종속 항목으로 추가할 수 있습니다.

하기 위해서:

1. pubspec.yaml 파일로 이동:

그리고 그것을 의존성으로 추가하십시오:

dependencies:
sqflite: ^0.12.1

최신 버전은 여기에서 확인할 수 있습니다.

2. 다운로드 해

Android Studio는 온라인 상태인 한 패키지를 가져오고 프로젝트에 추가하는 패키지 가져오기 버튼을 제공합니다.

Visual Studio 코드를 사용하는 경우 pubspec.yaml 파일을 변경하면 flutter packages get 명령이 자동으로 호출됩니다.

그렇지 않으면 위의 IDE를 사용하지 않는 경우 명령줄에서 설치할 수 있습니다.

$ flutter packages get

삼. 프로젝트로 가져오기

사용하려는 다트 코드로 이동하여 파일 상단에서 가져옵니다.

import 'package:sqflite/sqflite.dart';

Quick Flutter SQFLite 데이터베이스 하우투 스니펫

1. 데이터베이스 경로를 얻는 방법

        // Check if we have an existing copy first
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, "demo_asset_example.db");

2. 데이터베이스를 여는 방법

        // try opening (will work if it exists)
Database db;
try {
db = await openDatabase(path, readOnly: true);
} catch (e) {
print("Error $e");
}

도우미 클래스에 넣을 수 있습니다.

class Helper {
final String path;
Helper(this.path);
Database _db;
final _lock = Lock();
Future<Database> getDb() async {
if (_db == null) {
await _lock.synchronized(() async {
// Check again once entering the synchronized block
if (_db == null) {
_db = await openDatabase(path);
}
});
}
return _db;
}

또는:

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

여기서 initDb()는 경로를 가져오고 다음과 같이 여는 사용자 지정 메서드입니다.

  initDb() async {
io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, "test.db");
var theDb = await openDatabase(path, version: 1, onCreate: _onCreate);
return theDb;
}

3. 데이터베이스 테이블 생성 방법

S를 사용하여 flutter에서 데이터베이스 테이블을 만드는 방법을 살펴보겠습니다.

      var db = await openDatabase(path);
await db.execute("CREATE TABLE IF NOT EXISTS Test(id INTEGER PRIMARY KEY)");

또는:

  void _onCreate(Database db, int version) async {
// When creating the db, create the table
await db.execute(
"CREATE TABLE Employee(id INTEGER PRIMARY KEY, firstname TEXT, lastname TEXT, mobileno TEXT,emailId TEXT )");
print("Created tables");
}

dbDatabase 개체입니다. 우리는 그것의 execute() 메서드를 호출하고 원시 SQL 문을 전달하여 테이블을 생성합니다.

4. 데이터베이스 테이블에 삽입하는 방법

      await db.insert("Test", {"id": 1});

또는:

  Future<int> insertTodo(Todo todo) async {
Database db = await this.db;
var result = await db.insert(tblTodo, todo.toMap());
return result;
}

또는 자신의 속성을 가진 Person을 데이터베이스에 삽입하고 삽입된 사람을 반환하고 싶다고 가정해 보겠습니다.

  Future insertPerson(Person person) async {
person.id = await _db.insert("people", person.toMap());
return person;
}

또는

  void saveEmployee(Employee employee) async {
var dbClient = await db;
await dbClient.transaction((txn) async {
return await txn.rawInsert(
'INSERT INTO Employee(firstname, lastname, mobileno, emailid ) VALUES(' +
''' +
employee.firstName +
''' +
',' +
''' +
employee.lastName +
''' +
',' +
''' +
employee.mobileNo +
''' +
',' +
''' +
employee.emailId +
''' +
')');
});
}

5. SQLite 테이블에서 쿼리 또는 선택하는 방법

      await db.query("Test")

선택 항목을 반환하고 데이터베이스에서 사람 목록을 반환하고 싶다고 가정해 보겠습니다.

    Future fetchEveryone() async {
List results = await _db.query("people", columns: Person.columns);
List people = new List();
results.forEach((map) {
people.add(Person.fromMap(map));
});
return people;
}

또는 Flutter에서 SQlite 데이터베이스 목록을 쿼리하고 목록을 채우고 싶다고 합시다. rawQuery 메서드를 사용하여 원시 쿼리를 사용할 수도 있습니다. 실행할 SQL 문을 전달합니다.

  Future<List<Employee>> getEmployees() async {
var dbClient = await db;
List<Map> list = await dbClient.rawQuery('SELECT * FROM Employee');
List<Employee> employees = new List();
for (int i = 0; i < list.length; i++) {
employees.add(new Employee(list[i]["firstname"], list[i]["lastname"], list[i]["mobileno"], list[i]["emailid"]));
}
print(employees.length);
return employees;
}

또는 다른 예:

  Future<List> getTodos() async {
Database db = await this.db;
var result = await db.rawQuery("SELECT * FROM $tblTodo ORDER BY $colPriority ASC");
return result;
}

사용자가 로그인했는지 확인하고 싶다고 가정해 보겠습니다.

  Future<bool> isLoggedIn() async {
var dbClient = await db;
var res = await dbClient.query("User");
return res.length > 0 ? true : false;
}

7 . SQLite에서 항목 수를 계산하는 방법

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

7. SQFLite를 사용하여 SQLite 데이터베이스에서 데이터를 업데이트하는 방법

  Future<int> updateTodo(Todo todo) async {
var db = await this.db;
var result = await db.update(tblTodo, todo.toMap(),
where: "$colId = ?", whereArgs: [todo.id]);
return result;
}

7. SQFLite를 사용하여 SQLite 데이터베이스에서 삭제하는 방법

  Future<int> deleteTodo(int id) async {
int result;
var db = await this.db;
result = await db.rawDelete('DELETE FROM $tblTodo WHERE $colId = $id');
return result;
}

또는:

  Future<int> deleteUsers() async {
var dbClient = await db;
int res = await dbClient.delete("User");
return res;
}

6. 데이터베이스 닫기 방법

      await db.close();

또는:

  Future close() async {
await _db.close();
}

전체 예시

이제 Flutter SQFlite와 관련된 몇 가지 전체 예제를 살펴보겠습니다.

(ㅏ). Flutter SQFLite – 삽입, 선택, 표시

Flutter 애플리케이션에서 데이터 삽입, 선택 및 표시와 같은 기본 CRUD를 수행하는 방법을 보여주는 간단한 Dart Flutter 예제 자습서입니다. 우리는 SQFLite SQLite 플러그인을 사용할 것입니다. 이는 데이터베이스가 SQLite이기 때문입니다.

전체 예제 프로젝트

다음은 전체 소스 코드입니다.

(ㅏ). pubspec.yaml

우리의 의존성:

dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
path_provider: '>=0.3.0'
sqflite: any
dev_dependencies:
flutter_test:
sdk: flutter

(비). 직원 다트

이름, 성, 휴대폰 번호 및 이메일을 속성으로 가진 단일 직원을 나타내는 다트 클래스입니다. 이러한 속성은 생성자를 통해 수신됩니다.

class Employee {
String firstName;
String lastName;
String mobileNo;
String emailId;
Employee(this.firstName, this.lastName, this.mobileNo, this.emailId);
Employee.fromMap(Map map) {
firstName = map[firstName];
lastName = map[lastName];
mobileNo = map[mobileNo];
emailId = map[emailId];
}
}

(씨). dbhelper.dart

데이터베이스 crud 작업 구현에 도움이 되는 DBHelper 클래스:

import 'dart:async';
import 'dart:io' as io;
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_crud/model/employee.dart';
class DBHelper {
static Database _db;
Future<Database> get db async {
if (_db != null) return _db;
_db = await initDb();
return _db;
}
initDb() async {
io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, "test.db");
var theDb = await openDatabase(path, version: 1, onCreate: _onCreate);
return theDb;
}
void _onCreate(Database db, int version) async {
// When creating the db, create the table
await db.execute(
"CREATE TABLE Employee(id INTEGER PRIMARY KEY, firstname TEXT, lastname TEXT, mobileno TEXT,emailId TEXT )");
print("Created tables");
}
void saveEmployee(Employee employee) async {
var dbClient = await db;
await dbClient.transaction((txn) async {
return await txn.rawInsert(
'INSERT INTO Employee(firstname, lastname, mobileno, emailid ) VALUES(' +
''' +
employee.firstName +
''' +
',' +
''' +
employee.lastName +
''' +
',' +
''' +
employee.mobileNo +
''' +
',' +
''' +
employee.emailId +
''' +
')');
});
}
Future<List<Employee>> getEmployees() async {
var dbClient = await db;
List<Map> list = await dbClient.rawQuery('SELECT * FROM Employee');
List<Employee> employees = new List();
for (int i = 0; i < list.length; i++) {
employees.add(new Employee(list[i]["firstname"], list[i]["lastname"], list[i]["mobileno"], list[i]["emailid"]));
}
print(employees.length);
return employees;
}
}

####(디). emloyeelist.dart

이 파일에서 직원 목록은 목록 보기에서 비동기적으로 가져오고 렌더링됩니다.

import 'package:flutter/material.dart';
import 'package:flutter_crud/model/employee.dart';
import 'dart:async';
import 'package:flutter_crud/database/dbhelper.dart';
Future<List<Employee>> fetchEmployeesFromDatabase() async {
var dbHelper = DBHelper();
Future<List<Employee>> employees = dbHelper.getEmployees();
return employees;
}
class MyEmployeeList extends StatefulWidget {

MyEmployeeListPageState createState() => new MyEmployeeListPageState();
}
class MyEmployeeListPageState extends State<MyEmployeeList> {

Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Employee List'),
),
body: new Container(
padding: new EdgeInsets.all(16.0),
child: new FutureBuilder<List<Employee>>(
future: fetchEmployeesFromDatabase(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return new ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(snapshot.data[index].firstName,
style: new TextStyle(
fontWeight: FontWeight.bold, fontSize: 18.0)),
new Text(snapshot.data[index].lastName,
style: new TextStyle(
fontWeight: FontWeight.bold, fontSize: 14.0)),
new Divider()
]);
});
} else if (snapshot.hasError) {
return new Text("${snapshot.error}");
}
return new Container(alignment: AlignmentDirectional.center,child: new CircularProgressIndicator(),);
},
),
),
);
}
}

(e). 메인 다트

메인 메서드를 정의하는 메인 클래스, 다트 애플리케이션의 진입점:

import 'package:flutter/material.dart';
import 'package:flutter_crud/database/dbhelper.dart';
import 'package:flutter_crud/model/employee.dart';
import 'package:flutter_crud/employeelist.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.

Widget build(BuildContext context) {
return new MaterialApp(
title: 'SQFLite DataBase Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;

_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Employee employee = new Employee("", "", "", "");
String firstname;
String lastname;
String emailId;
String mobileno;
final scaffoldKey = new GlobalKey<ScaffoldState>();
final formKey = new GlobalKey<FormState>();

Widget build(BuildContext context) {
return new Scaffold(
key: scaffoldKey,
appBar: new AppBar(
title: new Text('Saving Employee'),
actions: <Widget>[
new IconButton(
icon: const Icon(Icons.view_list),
tooltip: 'Next choice',
onPressed: () {
navigateToEmployeeList();
},
),
]
),
body: new Padding(
padding: const EdgeInsets.all(16.0),
child: new Form(
key: formKey,
child: new Column(
children: [
new TextFormField(
keyboardType: TextInputType.text,
decoration: new InputDecoration(labelText: 'First Name'),
validator: (val) =>
val.length == 0 ?"Enter FirstName" : null,
onSaved: (val) => this.firstname = val,
),
new TextFormField(
keyboardType: TextInputType.text,
decoration: new InputDecoration(labelText: 'Last Name'),
validator: (val) =>
val.length ==0 ? 'Enter LastName' : null,
onSaved: (val) => this.lastname = val,
),
new TextFormField(
keyboardType: TextInputType.phone,
decoration: new InputDecoration(labelText: 'Mobile No'),
validator: (val) =>
val.length ==0 ? 'Enter Mobile No' : null,
onSaved: (val) => this.mobileno = val,
),
new TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: new InputDecoration(labelText: 'Email Id'),
validator: (val) =>
val.length ==0 ? 'Enter Email Id' : null,
onSaved: (val) => this.emailId = val,
),
new Container(margin: const EdgeInsets.only(top: 10.0),child: new RaisedButton(onPressed: _submit,
child: new Text('Save Employee'),),)
],
),
),
),
);
}
void _submit() {
if (this.formKey.currentState.validate()) {
formKey.currentState.save();
}else{
return null;
}
var employee = Employee(firstname,lastname,mobileno,emailId);
var dbHelper = DBHelper();
dbHelper.saveEmployee(employee);
_showSnackBar("Data saved successfully");
}
void _showSnackBar(String text) {
scaffoldKey.currentState
.showSnackBar(new SnackBar(content: new Text(text)));
}
void navigateToEmployeeList(){
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new MyEmployeeList()),
);
}
}

다운로드

가서 프로젝트를 다운로드하거나 github에서 찾아봅시다.

번호위치링크
1.GitHub직접 다운로드
2.GitHub찾아보기

위 프로젝트 @payen83의 원본 제작자에 대한 크레딧 및 감사

실행 방법

  1. 위의 프로젝트를 다운로드합니다.
  2. android studio/visual studio에서 정상적으로 애플리케이션을 생성합니다.
  3. pubspec.yaml을 편집하여 적절한 종속성을 추가합니다.
  4. 위의 dart 파일을 복사하여 프로젝트에 붙여넣습니다.

그 다음에:

장치 또는 에뮬레이터가 실행 중인지 확인하고 android studio에서 실행 버튼을 클릭하면 자동으로 장치를 선택하고 앱을 설치합니다.

Aletrnative 터미널 또는 명령 프롬프트를 사용할 수 있습니다. 프로젝트 루트 페이지로 이동/Cd하고 다음을 입력합니다.

flutter.bat build apk

이렇게 하면 기기에 드래그하여 설치할 수 있는 APK가 빌드됩니다. 내 컴퓨터의 빌드 프로세스는 나쁘지 않은 3분 정도 걸립니다.

예시 2: SQflite를 사용한 Flutter ToDo Notes 앱

이것은 또 다른 간단하고 이해하기 쉬운 SQFlite 샘플 프로젝트입니다. SQFlite를 활용하여 할일 항목을 저장하는 할일 앱입니다.

이 앱의 기능은 다음과 같습니다. 이 앱이 알려줄 내용은 다음과 같습니다.

  • 새 메모 추가
  • 업데이트 노트
  • 메모 삭제
  • 모든 메모 나열

데모 스크린샷은 다음과 같습니다.

시작하자.

1단계: 프로젝트 생성

원하는 편집기나 IDE에서 Flutter 프로젝트를 만드세요.

2단계: 종속성

pubspec.yaml로 이동하여 다음 종속 항목을 추가합니다.

dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.0
sqflite: ^1.3.2+1
path_provider: ^1.3.0
intl: ^0.16.1

가장 중요한 것은 로컬 sqlite 데이터베이스에 항목을 저장할 수 있는 sqflite입니다.

3단계: 모델 클래스 만들기

모델 클래스는 단일 ToDo 항목을 나타냅니다. 각 할 일에는 다음 필드가 있습니다.

  • ID - 할 일 항목의 고유 ID
  • NAME - 할 일 항목의 이름
  • 날짜 - 할 일 항목이 생성된 날짜입니다.

다음은 모델 클래스입니다.

TodoItem.dart

import 'package:flutter/material.dart';
class TodoItem extends StatelessWidget {
int _id;
String _itemName;
String _dateCreated;
TodoItem(this._itemName, this._dateCreated);
TodoItem.map(dynamic obj) {
this._itemName = obj['item_name'];
this._dateCreated = obj['date_created'];
this._id = obj['id'];
}
int get id => _id;
String get itemName => _itemName;
String get dateCreated => _dateCreated;
Map<String, dynamic> toMap() {
var map = Map<String, dynamic>();
map['item_name'] = this._itemName;
map['date_created'] = this._dateCreated;
if (this._id != null) {
map['id'] = this._id;
}
return map;
}
TodoItem.fromMap(Map<String, dynamic> map) {
this._id = map['id'];
this._itemName = map['item_name'];
this._dateCreated = map['date_created'];
}

Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
_itemName,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16.9),
),
Padding(
padding: const EdgeInsets.only(top : 8.0),
child: Text(
_dateCreated,
style: TextStyle(
color: Colors.white,
fontSize: 12.5,
fontStyle: FontStyle.italic,
),
),
)
],
),
);
}
}

4단계: 유틸리티 클래스 만들기

다음으로 와서 유틸리티 클래스를 만듭니다. 다음과 같은 두 개의 파일이 있습니다.

DatabaseHelper.dart

여기에서 SQFlite를 사용하여 SQLite 데이터베이스 작업을 위한 CRUD 함수를 작성할 것입니다.

예를 들어 다음 함수는 데이터베이스를 초기화하고 엽니다.

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

다음은 데이터베이스 테이블을 만드는 방법입니다.

  FutureOr<void> _onCreate(Database db, int version) async{
await db.execute(
"CREATE TABLE $tableItem ($columnId INTEGER PRIMARY KEY, $columnItemName TEXT, $columnDateCreated TEXT)"
);
}

데이터베이스에 삽입하거나 저장하는 방법은 다음과 같습니다.

  Future<int> saveItem(TodoItem item) async{
var dbClient = await db;
int res = await dbClient.insert('$tableItem', item.toMap());
return res;
}

다음은 데이터베이스에서 단일 항목을 검색하는 방법입니다.

  Future<TodoItem> getItem(int id) async {
var dbClient = await db;
var result = await dbClient.rawQuery('SELECT * FROM $tableItem WHERE $columnId = $id');
return TodoItem.fromMap(result.first);
}

다음은 SQFlite를 사용하여 SQLite 데이터베이스에서 모든 항목을 가져오는 방법입니다.

  Future<List> getAllItems() async {
var dbClient = await db;
var result = await dbClient.rawQuery('SELECT * FROM $tableItem ORDER BY $columnId DESC');
return result.toList();
}

다음은 데이터베이스의 항목 수를 계산하는 방법입니다.

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

데이터베이스에서 항목을 삭제하는 방법은 다음과 같습니다.

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

다음은 데이터베이스의 기존 항목을 업데이트하는 방법입니다.

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

다음은 데이터베이스를 닫는 것입니다.

  Future close() async {
var dbClient = await db;
return dbClient.close();
}

전체 코드는 다음과 같습니다.

import 'dart:async';
import 'dart:io';
import '../model/TodoItem.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseHelper {
static DatabaseHelper _instance = DatabaseHelper._internal();
static Database _db;
final String tableItem = "items";
final String columnId = "id";
final String columnItemName= "item_name";
final String columnDateCreated = "date_created";
factory DatabaseHelper() {
if (_instance == null) {
_instance = DatabaseHelper._internal();
}
return _instance;
}
DatabaseHelper._internal();
Future<Database> get db async {
if (_db != null) {
return _db;
}
_db = await initDb();
return _db;
}
initDb() async{
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = documentDirectory.path + "todo_db.db";
var db = await openDatabase(path, version: 1, onCreate: _onCreate);
return db;
}
FutureOr<void> _onCreate(Database db, int version) async{
await db.execute(
"CREATE TABLE $tableItem ($columnId INTEGER PRIMARY KEY, $columnItemName TEXT, $columnDateCreated TEXT)"
);
}
Future<int> saveItem(TodoItem item) async{
var dbClient = await db;
int res = await dbClient.insert('$tableItem', item.toMap());
return res;
}
Future<TodoItem> getItem(int id) async {
var dbClient = await db;
var result = await dbClient.rawQuery('SELECT * FROM $tableItem WHERE $columnId = $id');
return TodoItem.fromMap(result.first);
}
Future<List> getAllItems() async {
var dbClient = await db;
var result = await dbClient.rawQuery('SELECT * FROM $tableItem ORDER BY $columnId DESC');
return result.toList();
}
Future<int> getItemsCount() async {
var dbClient = await db;
return Sqflite.firstIntValue(
await dbClient.rawQuery('SELECT COUNT(*) FROM $tableItem')
);
}
Future<int> deleteItem(int id) async{
var dbClient = await db;
return await dbClient.delete(tableItem, where: "$columnId = ?", whereArgs: [id]);
}
Future<int> updateItem(TodoItem item) async {
var dbClient = await db;
return await dbClient.update(tableItem, item.toMap(), where: '$columnId = ?', whereArgs: [item.id]);
}
Future close() async {
var dbClient = await db;
return dbClient.close();
}
}

date_formatter.dart

이렇게 하면 날짜 형식이 지정됩니다. 전체 코드는 다음과 같습니다.

import 'package:intl/intl.dart';
String dateFormatted() {
var date = DateTime.now();
var formatter = DateFormat("EEE, MMM d, ''yy");
String formattedDate = formatter.format(date);
return formattedDate;
}

5단계: UI 위젯 만들기

이 경우 두 가지 위젯이 있습니다.

(ㅏ). 홈.다트

이것은 홈 화면을 나타냅니다:

import 'package:flutter/material.dart';
import 'TodoScreen.dart';
class Home extends StatelessWidget {

Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Todo App'),
backgroundColor: Colors.indigoAccent,
),
body: TodoScreen(),
);
}
}

TodoScreen.dart

이렇게 하면 할 일 항목을 입력하고 편집하는 데 사용되는 대화 상자가 구성됩니다. 전체 코드는 다음과 같습니다.

import 'package:flutter/material.dart';
import 'package:todo_app/util/DatabaseHelper.dart';
import '../model/TodoItem.dart';
import 'package:todo_app/util/date_formatter.dart';
class TodoScreen extends StatefulWidget {

_TodoScreenState createState() => _TodoScreenState();
}
class _TodoScreenState extends State<TodoScreen> {
final TextEditingController _textEditingController = TextEditingController();
var dbHelper = DatabaseHelper();
List<TodoItem> _itemsList = List<TodoItem>();

void initState() {
super.initState();
_readTodoItemsList();
}

Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Flexible(
child: ListView.builder(
itemBuilder: (_, int position) {
return Card(
color: Colors.brown,
child: ListTile(
title: _itemsList[position],
onTap: () => _updateTodoItemDialog(_itemsList[position], position),
trailing: Listener(
key: Key(_itemsList[position].itemName),
child: Icon(
Icons.delete,
color: Colors.redAccent,
),
onPointerDown: (pointerEvent) => _deleteTodoItem(_itemsList[position].id, position)
,
),
),
);
},
padding: EdgeInsets.all(8.0),
reverse: false,
itemCount: _itemsList.length,
),
)
],
),
backgroundColor: Colors.white10,
floatingActionButton: FloatingActionButton(
onPressed: _showFormDialog,
child: Icon(Icons.add),
backgroundColor: Colors.redAccent,
tooltip: 'Tap to add item',
),
);
}
void _showFormDialog() {
var alert = AlertDialog(
content: Row(
children: <Widget>[
Expanded(
child: TextField(
controller: _textEditingController,
decoration: InputDecoration(
labelText: 'Item',
hintText: 'Add new item',
icon: Icon(Icons.note_add)),
))
],
),
actions: <Widget>[
FlatButton(
onPressed: () {
_handleSubmit(_textEditingController.text);
_textEditingController.clear();
Navigator.pop(context);
},
child: Text('Add')),
FlatButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Cancel'),
)
],
);
showDialog(
context: context,
builder: (_) {
return alert;
});
}
_handleSubmit(String text) async {
_textEditingController.clear();
var item = TodoItem(text, dateFormatted());
int savedItemId = await dbHelper.saveItem(item);
var addedItem = await dbHelper.getItem(savedItemId);
setState(() {
_itemsList.insert(0, addedItem);
});
}
_readTodoItemsList() async {
var items = await dbHelper.getAllItems();
print('List $_itemsList');
items.forEach((item) {
setState(() {
var todoItem = TodoItem.fromMap(item);
_itemsList.add(todoItem);
});
});
}
_deleteTodoItem(int id, int position) async{
await dbHelper.deleteItem(id);
setState(() {
_itemsList.removeAt(position);
});
}
_updateTodoItemDialog(TodoItem item, int position) {
var alert = AlertDialog(
title: Text(
'Update Item'
),
content: Row(
children: <Widget>[
Expanded(
child: TextField(
controller: _textEditingController,
decoration: InputDecoration(
labelText: 'Item',
icon: Icon(Icons.update)
),
),
)
],
),
actions: <Widget>[
FlatButton(onPressed: () async{
TodoItem updatedItem = TodoItem.fromMap({
'item_name' : _textEditingController.text,
'date_created' : dateFormatted(),
'id' : item.id
});
_handleSubmittedUpdate(position, item);
await dbHelper.updateItem(updatedItem);
setState(() {
_readTodoItemsList();
});
Navigator.pop(context);
}, child: Text(
'Update'
)),
FlatButton(onPressed: () => Navigator.pop(context), child: Text(
'Cancel'
))
],
);
showDialog(context: context, builder: (_) {
return alert;
});
}
void _handleSubmittedUpdate(int position, TodoItem item) {
_itemsList.removeWhere((element) => _itemsList[position].id == item.id);
}
}

6단계: 메인 클래스 만들기

우리의 메인 클래스는 MyApp이라는 stateless 위젯이 될 것입니다. 전체 코드는 다음과 같습니다.

메인.다트

import 'package:flutter/material.dart';
import 'ui/Home.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.

Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
home: Home(),
);
}
}

달리다

코드를 복사하거나 아래 링크에서 다운로드하여 빌드하고 실행합니다.

참조

참조 링크는 다음과 같습니다.

번호링크
1.다운로드 예시
2.팔로우 코드 작성자