💬

driftを使ってToDoアプリを作ってみる

2022/06/04に公開

初記事です。

ずっとFlutterを勉強してるのですが
成果が分かりずらいので記事書きやってみたいと思います。

参考記事

今回はdriftです。
driftはスマホ内でデータベースを保存できるツールです。

アプリの動き

今回使用するパッケージ
https://pub.dev/packages/drift

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  drift: ^1.5.0
  path: ^1.8.0
  path_provider: ^2.0.9
  sqlite3_flutter_libs: ^0.5.5

dev_dependencies:
  flutter_test:
    sdk: flutter

  flutter_lints: ^1.0.0
  build_runner: ^2.1.11
  drift_dev: ^1.5.2

まずは大枠の作成

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: DriftHome(),
    );
  }
}

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

  
  State<DriftHome> createState() => _DriftHomeState();
}

class _DriftHomeState extends State<DriftHome> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('TODO-DRIFT'),
        backgroundColor: Colors.cyan,
      ),
      body: SafeArea(
        child: Column(
          children: [
            TextButton(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(
                    'ここにタイトルを入力',
                    style: TextStyle(color: Colors.black, fontSize: 20),
                  ),
                ],
              ),
              onPressed: () {}, //ワンタッチ処理※これを書かないとエラー
              onLongPress: () {}, //長押し処理
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton.extended(
        icon: Icon(Icons.notes),
        foregroundColor: Colors.black, //文字色
        backgroundColor: Colors.amber, //背景色
        label: Text('Add ToDo Page'),
        onPressed: () {},
      ),
    );
  }
}
add_page.dart
import 'package:flutter/material.dart';

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

  
  State<AddPage> createState() => _AddPageState();
}

class _AddPageState extends State<AddPage> {
  final TextEditingController textCon =TextEditingController();
  final TextEditingController alphaCon =TextEditingController();

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('AddPage'),
      ),
      body: Column(
        children: [
          TextFormField(
            controller: textCon,
            decoration: InputDecoration(
              hintText: '文字列を入力',
              labelText: '文字列左'
            ),
          ),
          TextFormField(
            controller: alphaCon,
            decoration: InputDecoration(
                hintText: '文字列を入力',
                labelText: '文字列右'
            ),
          ),
        ],
      ),
    );
  }
}

今回は編集画面を追加画面を同じにするので
コードを複製します。(多分もっといい方法があるはず...)

一部、修正

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

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

  
  State<EditPage> createState() => _EditPageState();
}

class _EditPageState extends State<EditPage> {
  final TextEditingController textCon =TextEditingController();
  final TextEditingController alphaCon =TextEditingController();

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('EditPage'),
        backgroundColor: Colors.greenAccent,
      ),
      body: Column(
        children: [
          TextFormField(
            controller: textCon,
            decoration: InputDecoration(
                hintText: '文字列を入力',
                labelText: '文字列左'
            ),
          ),
          TextFormField(
            controller: alphaCon,
            decoration: InputDecoration(
                hintText: '文字列を入力',
                labelText: '文字列右'
            ),
          ),
        ],
      ),
    );
  }
}

これで画面構成の大枠は完成です。

Picture

![]

続いてdrift部分

todo_try_db.dart
import 'package:drift/drift.dart';

// ファイル名+g.dartの形式で記載
part 'todo_try_db.g.dart';


//データベースのテーブルを定義
//クラス名をTodoTry-->テーブル名がTodoTryになる
//Column=列でid(int),textLeft(String),textRight(String)を持っています。
//autoIncrement()を設定すると、データ追加時に自動生成される
class TodoTry extends Table{
  IntColumn get id=>integer().autoIncrement()();
  TextColumn get textLeft=>text()();
  TextColumn get textRight=>text()();
}

//データベースクラスの定義
//生成処理やデータの追加処理などを記載
//@DriftDatabase(tables:[TodoTry])でデータベースとテーブルの紐づけができる
(tables:[TodoTry])
class MyDB extends _$MyDB{}

コードの自動生成

flutter pub run build_runner build 

再生成するときは

flutter pub run build_runner build --delete-conflicting-outputs
ターミナル文
[INFO] Generating build script...
[INFO] Generating build script completed, took 416ms

[INFO] Precompiling build script......
[INFO] Precompiling build script... completed, took 7.6s

[INFO] Initializing inputs
[INFO] Building new asset graph...
[INFO] Building new asset graph completed, took 985ms

[INFO] Checking for unexpected pre-existing outputs....
[INFO] Checking for unexpected pre-existing outputs. completed, took 2ms

[INFO] Running build...
[INFO] Generating SDK summary...
[INFO] 3.5s elapsed, 0/5 actions completed.
[INFO] Generating SDK summary completed, took 3.5s

[INFO] 4.5s elapsed, 0/5 actions completed.
[INFO] 5.6s elapsed, 0/5 actions completed.
[INFO] 6.6s elapsed, 0/5 actions completed.
[INFO] 7.7s elapsed, 0/5 actions completed.
[INFO] 13.5s elapsed, 0/5 actions completed.
[INFO] Running build completed, took 14.3s

[INFO] Caching finalized dependency graph...
[INFO] Caching finalized dependency graph completed, took 36ms

[INFO] Succeeded after 14.4s with 2 outputs (11 actions)

todo_try_db.g.dart(自動生成コード)
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'todo_try_db.dart';

// **************************************************************************
// MoorGenerator
// **************************************************************************

// ignore_for_file: unnecessary_brace_in_string_interps, unnecessary_this
class TodoTryData extends DataClass implements Insertable<TodoTryData> {
  final int id;
  final String textLeft;
  final String textRight;
  TodoTryData(
      {required this.id, required this.textLeft, required this.textRight});
  factory TodoTryData.fromData(Map<String, dynamic> data, {String? prefix}) {
    final effectivePrefix = prefix ?? '';
    return TodoTryData(
      id: const IntType()
          .mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
      textLeft: const StringType()
          .mapFromDatabaseResponse(data['${effectivePrefix}text_left'])!,
      textRight: const StringType()
          .mapFromDatabaseResponse(data['${effectivePrefix}text_right'])!,
    );
  }
  
  Map<String, Expression> toColumns(bool nullToAbsent) {
    final map = <String, Expression>{};
    map['id'] = Variable<int>(id);
    map['text_left'] = Variable<String>(textLeft);
    map['text_right'] = Variable<String>(textRight);
    return map;
  }

  TodoTryCompanion toCompanion(bool nullToAbsent) {
    return TodoTryCompanion(
      id: Value(id),
      textLeft: Value(textLeft),
      textRight: Value(textRight),
    );
  }

  factory TodoTryData.fromJson(Map<String, dynamic> json,
      {ValueSerializer? serializer}) {
    serializer ??= driftRuntimeOptions.defaultSerializer;
    return TodoTryData(
      id: serializer.fromJson<int>(json['id']),
      textLeft: serializer.fromJson<String>(json['textLeft']),
      textRight: serializer.fromJson<String>(json['textRight']),
    );
  }
  
  Map<String, dynamic> toJson({ValueSerializer? serializer}) {
    serializer ??= driftRuntimeOptions.defaultSerializer;
    return <String, dynamic>{
      'id': serializer.toJson<int>(id),
      'textLeft': serializer.toJson<String>(textLeft),
      'textRight': serializer.toJson<String>(textRight),
    };
  }

  TodoTryData copyWith({int? id, String? textLeft, String? textRight}) =>
      TodoTryData(
        id: id ?? this.id,
        textLeft: textLeft ?? this.textLeft,
        textRight: textRight ?? this.textRight,
      );
  
  String toString() {
    return (StringBuffer('TodoTryData(')
          ..write('id: $id, ')
          ..write('textLeft: $textLeft, ')
          ..write('textRight: $textRight')
          ..write(')'))
        .toString();
  }

  
  int get hashCode => Object.hash(id, textLeft, textRight);
  
  bool operator ==(Object other) =>
      identical(this, other) ||
      (other is TodoTryData &&
          other.id == this.id &&
          other.textLeft == this.textLeft &&
          other.textRight == this.textRight);
}

class TodoTryCompanion extends UpdateCompanion<TodoTryData> {
  final Value<int> id;
  final Value<String> textLeft;
  final Value<String> textRight;
  const TodoTryCompanion({
    this.id = const Value.absent(),
    this.textLeft = const Value.absent(),
    this.textRight = const Value.absent(),
  });
  TodoTryCompanion.insert({
    this.id = const Value.absent(),
    required String textLeft,
    required String textRight,
  })  : textLeft = Value(textLeft),
        textRight = Value(textRight);
  static Insertable<TodoTryData> custom({
    Expression<int>? id,
    Expression<String>? textLeft,
    Expression<String>? textRight,
  }) {
    return RawValuesInsertable({
      if (id != null) 'id': id,
      if (textLeft != null) 'text_left': textLeft,
      if (textRight != null) 'text_right': textRight,
    });
  }

  TodoTryCompanion copyWith(
      {Value<int>? id, Value<String>? textLeft, Value<String>? textRight}) {
    return TodoTryCompanion(
      id: id ?? this.id,
      textLeft: textLeft ?? this.textLeft,
      textRight: textRight ?? this.textRight,
    );
  }

  
  Map<String, Expression> toColumns(bool nullToAbsent) {
    final map = <String, Expression>{};
    if (id.present) {
      map['id'] = Variable<int>(id.value);
    }
    if (textLeft.present) {
      map['text_left'] = Variable<String>(textLeft.value);
    }
    if (textRight.present) {
      map['text_right'] = Variable<String>(textRight.value);
    }
    return map;
  }

  
  String toString() {
    return (StringBuffer('TodoTryCompanion(')
          ..write('id: $id, ')
          ..write('textLeft: $textLeft, ')
          ..write('textRight: $textRight')
          ..write(')'))
        .toString();
  }
}

class $TodoTryTable extends TodoTry with TableInfo<$TodoTryTable, TodoTryData> {
  
  final GeneratedDatabase attachedDatabase;
  final String? _alias;
  $TodoTryTable(this.attachedDatabase, [this._alias]);
  final VerificationMeta _idMeta = const VerificationMeta('id');
  
  late final GeneratedColumn<int?> id = GeneratedColumn<int?>(
      'id', aliasedName, false,
      type: const IntType(),
      requiredDuringInsert: false,
      defaultConstraints: 'PRIMARY KEY AUTOINCREMENT');
  final VerificationMeta _textLeftMeta = const VerificationMeta('textLeft');
  
  late final GeneratedColumn<String?> textLeft = GeneratedColumn<String?>(
      'text_left', aliasedName, false,
      type: const StringType(), requiredDuringInsert: true);
  final VerificationMeta _textRightMeta = const VerificationMeta('textRight');
  
  late final GeneratedColumn<String?> textRight = GeneratedColumn<String?>(
      'text_right', aliasedName, false,
      type: const StringType(), requiredDuringInsert: true);
  
  List<GeneratedColumn> get $columns => [id, textLeft, textRight];
  
  String get aliasedName => _alias ?? 'todo_try';
  
  String get actualTableName => 'todo_try';
  
  VerificationContext validateIntegrity(Insertable<TodoTryData> instance,
      {bool isInserting = false}) {
    final context = VerificationContext();
    final data = instance.toColumns(true);
    if (data.containsKey('id')) {
      context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
    }
    if (data.containsKey('text_left')) {
      context.handle(_textLeftMeta,
          textLeft.isAcceptableOrUnknown(data['text_left']!, _textLeftMeta));
    } else if (isInserting) {
      context.missing(_textLeftMeta);
    }
    if (data.containsKey('text_right')) {
      context.handle(_textRightMeta,
          textRight.isAcceptableOrUnknown(data['text_right']!, _textRightMeta));
    } else if (isInserting) {
      context.missing(_textRightMeta);
    }
    return context;
  }

  
  Set<GeneratedColumn> get $primaryKey => {id};
  
  TodoTryData map(Map<String, dynamic> data, {String? tablePrefix}) {
    return TodoTryData.fromData(data,
        prefix: tablePrefix != null ? '$tablePrefix.' : null);
  }

  
  $TodoTryTable createAlias(String alias) {
    return $TodoTryTable(attachedDatabase, alias);
  }
}

abstract class _$MyDB extends GeneratedDatabase {
  _$MyDB(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e);
  late final $TodoTryTable todoTry = $TodoTryTable(this);
  
  Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>();
  
  List<DatabaseSchemaEntity> get allSchemaEntities => [todoTry];
}

データベースの生成

todo_try_db.dart
import 'package:drift/drift.dart';
//下記のパッケージを追加
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:drift/native.dart';
import 'package:path/path.dart' as p_dev;

part 'todo_try_db.g.dart';

class TodoTry extends Table{
  IntColumn get id=>integer().autoIncrement()();
  TextColumn get textLeft=>text()();
  TextColumn get textRight=>text()();
}


(tables:[TodoTry])
class MyDB extends _$MyDB{
  //データベースのインスタンス生成と同時にデータベースとの接続処理を行う
  MyDB() : super(_openConnection());

  //データベースのバージョン指定
  
  int get schemaVersion=>1;

}

//データベースの保存位置を取得する設定
LazyDatabase _openConnection(){
  return LazyDatabase(()async{
    final dbFolder=await getApplicationDocumentsDirectory();
    final file=File(p_dev.join(dbFolder.path,'db.sqlite'));
    return NativeDatabase(file);
  });
}

データベースの生成を行うためにmain.dartのmain関数の中で、runApp()の前に行う。

main.dart
void main() {
  final database=MyDB();
  runApp(const MyApp());
}

データの表示

todo_try_db.dart
//データベースクラスの定義
//生成処理やデータの追加処理などを記載
//@DriftDatabase(tables:[TodoTry])でデータベースとテーブルの紐づけができる
(tables:[TodoTry])
class MyDB extends _$MyDB{
  //データベースのインスタンス生成と同時にデータベースとの接続処理を行う
  MyDB() : super(_openConnection());

  //データベースのバージョン指定
  
  int get schemaVersion=>1;
  //Streamでデータ取得する,selectでデータ選択,getでデータ取得
  Stream<List<TodoTryData>> watchEnries(){
    return (select(todoTry)).watch();
  }
  //Futureを用いてデータを取得
  //selectでデータ選択,getでデータ取得
  //データの監視を続けるためにStreamを用いて,main.dartにStreamBuilderを追加
  Future<List<TodoTryData>> get allTodoEntries =>select(todoTry).get();
}

databaseの受け渡し&StreamBuilderの追加

main.dart
import 'package:drift_220605/add_page.dart';
import 'package:drift_220605/todo_try_db.dart';
import 'package:flutter/material.dart';

void main() {
  final database = MyDB();
  runApp(MyApp(db: database));
}

class MyApp extends StatelessWidget {
  const MyApp({
    Key? key,
    required this.db,
  }) : super(key: key);

  final MyDB db;

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DriftHome(db: db),
    );
  }
}

class DriftHome extends StatefulWidget {
  const DriftHome({
    Key? key,
    required this.db,
  }) : super(key: key);
  final MyDB db;

  
  State<DriftHome> createState() => _DriftHomeState();
}

class _DriftHomeState extends State<DriftHome> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('TODO-DRIFT'),
        backgroundColor: Colors.cyan,
      ),
      body: SafeArea(
        child: Column(
          children: [
            Expanded(
              child: StreamBuilder(
                stream: widget.db.watchEnries(),
                builder: (BuildContext context,
                    AsyncSnapshot<List<TodoTryData>> snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return const Center(
                      child: CircularProgressIndicator(),
                    );
                  }
                  return ListView.builder(
                      itemCount: snapshot.data!.length,
                      itemBuilder: (context, index) {
                        return Padding(
                          padding: const EdgeInsets.all(4.0),
                          child: Container(
                            decoration: BoxDecoration(
                              border: Border.all(color: Colors.black, width: 3),
                              borderRadius: BorderRadius.circular(10),
                            ),
                            child: TextButton(
                              child: Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: [
                                  Text(
                                    snapshot.data![index].textLeft,
                                    style: TextStyle(
                                        color: Colors.black, fontSize: 20),
                                  ),
                                  Text(
                                    snapshot.data![index].textRight,
                                    style: TextStyle(
                                        color: Colors.black, fontSize: 20),
                                  ),
                                ],
                              ),
                              onLongPress: () async {},
                              onPressed: () async {},
                            ),
                          ),
                        );
                      });
                },
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton.extended(
        icon: Icon(Icons.notes),
        foregroundColor: Colors.black,
        //文字色
        backgroundColor: Colors.amber,
        //背景色
        label: Text('Add ToDo Page'),
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => AddPage(),
            ),
          );
        },
      ),
    );
  }
}

database.watchEntriesでデータの取得を行う

本当は状態管理した方がいいけど今回はパス

todo_try_db.dart
 //データベースのバージョン指定
  
  int get schemaVersion => 1;

  
  Stream<List<TodoTryData>> watchEnries() {
    return (select(todoTry)).watch();
  }

  Future<List<TodoTryData>> get allTodoEntries => select(todoTry).get();

  //追加処理
  //into...データ追加するテーブルの指定
  //insert...データクラスであるTodoTryCompanionを追加
  //TodoTryCompanion...データの追加や後進に有用なデータクラス
  //このデータクラスを使うことにより、idを指定せずにデータを追加したいときなど、一部のデータだけを追加できる
  Future<int> addTodoTry(String textLeft, String textRight) {
    return into(todoTry).insert(TodoTryCompanion(
        textLeft: Value(textLeft), textRight: Value(textRight)));
  }
main.dart
      floatingActionButton: FloatingActionButton.extended(
        icon: Icon(Icons.notes),
        foregroundColor: Colors.black,
        //文字色
        backgroundColor: Colors.amber,
        //背景色
        label: Text('Add ToDo Page'),
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(
              //追加
              builder: (context) => AddPage(db: widget.db,),
            ),
          );
        },
      ),
add_page.dart
import 'package:drift_220605/main.dart';
import 'package:drift_220605/todo_try_db.dart';
import 'package:flutter/material.dart';

class AddPage extends StatefulWidget {
  //追加
  const AddPage({Key? key,required this.db}) : super(key: key);
  final MyDB db;

  
  State<AddPage> createState() => _AddPageState();
}

class _AddPageState extends State<AddPage> {
  final TextEditingController textCon =TextEditingController();
  final TextEditingController alphaCon =TextEditingController();

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.greenAccent,
        title: Text('AddPage'),
      ),
      body: Column(
        children: [
          TextFormField(
            controller: textCon,
            decoration: InputDecoration(
              hintText: '文字列を入力',
              labelText: '文字列左'
            ),
          ),
          TextFormField(
            controller: alphaCon,
            decoration: InputDecoration(
                hintText: '文字列を入力',
                labelText: '文字列右'
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton.extended(
        icon: Icon(Icons.plus_one),
        foregroundColor: Colors.black,
        //文字色
        backgroundColor: Colors.greenAccent,
        //背景色
        label: Text('Add ToDo Page'),

        //追加
        //空欄の場合はボタンを押せないようにする
        onPressed: () async{
          if(textCon.text!=""){
            if(alphaCon.text!=""){
              await widget.db.addTodoTry(textCon.text, alphaCon.text);
              Navigator.push(
                context,
                MaterialPageRoute(
                  //追加
                  builder: (context) => DriftHome(db: widget.db,),
                ),
              );
            }
          }

        },
      ),
    );
  }
}

表示を変更

main.dart
                              child: Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: [
                                  Expanded(
                                    child: Center(
                                      child: Text(
                                        snapshot.data![index].textLeft,
                                        style: TextStyle(
                                            color: Colors.black, fontSize: 20),
                                      ),
                                    ),
                                  ),
                                  Expanded(
                                    child: Center(
                                      child: Text(
                                        snapshot.data![index].textRight,
                                        style: TextStyle(
                                            color: Colors.black, fontSize: 20),
                                      ),
                                    ),
                                  ),
                                ],
                              ),

画像!

データの更新

main.dart
                              //編集処理
                              onPressed: () async {
                                final todolist = await widget.db.allTodoEntries;
                                Navigator.push(
                                    context,
                                    MaterialPageRoute(
                                        builder: (context) => EditPage(
                                              db: widget.db,
                                              editTextL: snapshot
                                                  .data![index].textLeft,
                                              editTextR: snapshot
                                                  .data![index].textRight,
                                              index: index,
                                            )));
                              },
edit_page.dart
import 'package:drift_220605/main.dart';
import 'package:drift_220605/todo_try_db.dart';
import 'package:flutter/material.dart';

class EditPage extends StatefulWidget {
  const EditPage({Key? key,
    required this.db,
    required this.editTextL,
    required this.editTextR,
    required this.index})
      : super(key: key);

  final MyDB db;
  final String? editTextL;
  final String? editTextR;
  final int? index;

  
  State<EditPage> createState() => _EditPageState();
}

class _EditPageState extends State<EditPage> {
  // final TextEditingController textCon = TextEditingController();
  // final TextEditingController alphaCon = TextEditingController();

  
  void initState() {
    super.initState();
    final textCon = TextEditingController(text: widget.editTextL);
    final alphaCon = TextEditingController(text: widget.editTextR);
  }

  
  Widget build(BuildContext context) {
    final TextEditingController textCon = TextEditingController();
    final TextEditingController alphaCon = TextEditingController();
    textCon.text = widget.editTextL ?? "";
    alphaCon.text = widget.editTextR ?? "";

    return Scaffold(
      appBar: AppBar(
        title: Text('EditPage'),
        backgroundColor: Colors.greenAccent,
      ),
      body: Column(
        children: [
          TextFormField(
            controller: textCon,
            decoration: InputDecoration(
                hintText: '文字列を入力', labelText: '文字列左'),
          ),
          TextFormField(
            controller: alphaCon,
            decoration: InputDecoration(
                hintText: '文字列を入力', labelText: '文字列右'),
          ),
        ],
      ),
      floatingActionButton: StreamBuilder(
          stream: widget.db.watchEnries(),
          builder: (BuildContext context,
              AsyncSnapshot<List<TodoTryData>> snapshot) {
            return FloatingActionButton.extended(
                icon: Icon(Icons.plus_one),
                label: Text("Edit ToDo"),
                backgroundColor: (textCon.text == "") ? Colors.black : Colors
                    .red,
                onPressed: () async {
                  if (textCon.text != null) {
                    // await widget.database.addTodo(textCon.text);
                    await widget.db.updateTodoTry(
                        snapshot.data![widget.index!], textCon.text,
                        alphaCon.text);
                    Navigator.push(context, MaterialPageRoute(
                        builder: (context) => DriftHome(db: widget.db,)));
                  }
                }
            );
          }
      ),
    );
  }
}
todo_try_db.dart.dart
  //更新
  Future<int> updateTodoTry(TodoTryData todoTryData,String textLeft, String textRight){
    return (update(todoTry)..where((tbl) => tbl.id.equals(todoTryData.id)))
        .write(TodoTryCompanion(
      textLeft: Value(textLeft),
      textRight: Value(textRight),
    ));
  }

GIF

削除

main.dart
                              onLongPress: () async {
                                final list =
                                await widget.db.allTodoEntries;
                                if (list.isNotEmpty) {
                                  await widget.db.deleteTodoTry(list[index]);
                                }
                              },
todo_try_db.dart
 //編集の下に
  //削除
  Future<void> deleteTodoTry(TodoTryData todolistData){
    return (delete(todoTry)..where((tbl) => tbl.id.equals(todolistData.id))).go();
  }

GIF

これで一連の流れは完成です。

今回はAoiさんの記事を参考にしました。
ありがとうございました!

【Flutter】 Drift の基本的な使い方解説 #Flutter大学

https://blog.flutteruniv.com/flutter-drift/
@Aoi_Umigishiより

Discussion