フリーランス 技術調査ブログ

フリーランス/エンジニア Ruby Python Nodejs Vuejs React Dockerなどの調査技術調査の備忘録

Flutterでsqlliteを利用してタスク管理を実装する

はじめに

  • 作成途中のプログラムになりますが、Flutterでsqlliteを利用してタスクの登録と削除を行えるアプリを開発する。 ※変更処理は途中の状態です。

インストールのパッケージ

  • sqfliteとpath_providerをインストールする
dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  sqflite: ^2.0.2
  path_provider: ^2.0.8

コード

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';

import 'next_page.dart';


void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
  final textController = TextEditingController();
  int? selectedId;
  int tabIndex = 1;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home:Scaffold(
          appBar: AppBar(
              title: Text("タスク管理")
          ),
          body: Center(
            child: FutureBuilder<List<Task>>(
                future: DatabaseHelper.instance.getTasks(),
                builder: (BuildContext context,
                    AsyncSnapshot<List<Task>> snapshot) {
                  if (!snapshot.hasData) {
                    return Center(child: Text('Loading...'));
                  }
                  return snapshot.data!.isEmpty
                      ? Center(child: Text('No Tasks.'))
                      : ListView(
                    children: snapshot.data!.map((task) {
                      return Center(
                          child: Card(
                            color: selectedId == task.id
                                ? Colors.white70
                                : Colors.white,
                            child: ListTile(
                              title: Text(task.name),
                              onTap: () {
                                if (selectedId == null) {
                                  textController.text = task.name;
                                  selectedId = task.id;
                                } else {
                                  textController.text = '';
                                  selectedId = null;
                                }
                              },
                              onLongPress: () {
                                setState(() {
                                  DatabaseHelper.instance.remove(task.id!);
                                });
                              },
                            ),
                          )
                      );
                    }).toList(),
                  );
                }),
          ),
          floatingActionButton: FloatingActionButton(
            child: Icon(Icons.save),
            onPressed: ()async {
              selectedId != null
                  ? await DatabaseHelper.instance.update(
                Task(id: selectedId, name: textController.text),
              )
                  : await DatabaseHelper.instance.add(
                Task(name: textController.text),
              );
              setState(() {
                textController.clear();
                selectedId = null;
              });
            },
          ),
          bottomNavigationBar: BottomNavigationBar(
            currentIndex: tabIndex,
            items: [
              BottomNavigationBarItem(
                label: 'Home',
                icon: Icon(Icons.home),
              ),
              BottomNavigationBarItem(
                label: 'AC Unit',
                icon: Icon(Icons.ac_unit),
              ),
            ],
            onTap: (int index) {
                setState((){
                  tabIndex = index;
                });
                showDialog(
                  context: context,
                  builder: (_) {
                    return AlertDialog(
                      title: Text("タイトル"),
                      content: TextField(
                        controller: textController,
                      ),
                      actions: <Widget>[
                        // ボタン領域
                        ElevatedButton(
                          child: Text("Cancel"),
                          onPressed: () => Navigator.pop(context),
                        ),
                        ElevatedButton(
                          child: Text("OK"),
                          onPressed: () async {
                            selectedId != null
                                ? await DatabaseHelper.instance.update(
                              Task(id: selectedId, name: textController.text),
                            )
                                : await DatabaseHelper.instance.add(
                              Task(name: textController.text),
                            );
                            setState(() {
                              textController.clear();
                              selectedId = null;
                            });
                            //Navigator.push(context, MaterialPageRoute(builder: (context) => NextPage()))
                          },
                        ),
                      ],
                    );
                  },
                );
                //Navigator.push(context, MaterialPageRoute(builder: (context) => NextPage()));
            },
          ),
        )
    );
  }
}

class Task {
  final int? id;
  final String name;

  Task({this.id, required this.name});

  factory Task.fromMap(Map<String, dynamic>json) => new Task(
      id: json['id'],
      name: json['name']
  );

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'name': name
    };
  }
}

class DatabaseHelper {
  DatabaseHelper._privateConstructor();
  static final DatabaseHelper instance = DatabaseHelper._privateConstructor();

  static Database? _database;
  Future<Database> get database async => _database ??= await _initDatabase();

  Future<Database> _initDatabase() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, 'tasks.db');
    return await openDatabase(
      path,
      version: 1,
      onCreate: _onCreate,
    );
  }

  Future _onCreate(Database db, int version) async {
    await db.execute('''
      CREATE TABLE tasks(
          id INTEGER PRIMARY KEY,
          name TEXT
      )
      ''');
  }

  Future<List<Task>> getTasks() async {
    Database db = await instance.database;
    var tasks = await db.query('tasks', orderBy: 'name');
    List<Task> taskList = tasks.isNotEmpty
        ? tasks.map((c) => Task.fromMap(c)).toList()
        : [];
    return taskList;
  }
  Future<int> update(Task task) async {
    Database db = await instance.database;
    return await db.update('tasks', task.toMap(),
        where: "id = ?", whereArgs: [task.id]);
  }

  Future<int> add(Task task) async {
    Database db = await instance.database;
    return await db.insert('tasks', task.toMap());
  }

  Future<int> remove(int id) async {
    Database db = await instance.database;
    return await db.delete('tasks', where: 'id = ?', whereArgs: [id]);
  }
}

作成した画面

f:id:PX-WING:20220121201314p:plain