todo appをFlutterで作るハンズオン

3.2K Views

August 14, 22

スライド概要

Flutterを使ったTodo app ハンズオン用のスライドです

profile-image

狐とFlutterが好きなプログラマ

Docswellを使いましょう

(ダウンロード不可)

関連スライド

各ページのテキスト
1.

Todo アプリ ハンズオン Todo アプリハンズオン by Flutter pregum pregum 1

2.

アプリ ハンズオン 目次 Todo 最初に とは? Flutter とネイティブアプリとの違い なぜ他のXPではなくFlutterなのか? 今日作るアプリについて TodoApp 作成 ( 時間があれば ) 、質疑応答 Flutter pregum 2

3.

Todo アプリ ハンズオン 最初に 今日はハンズオンに参加していただき、ありがとうございます。 1 点お願いがあります。 サンプルのカウンターアプリが起動ができていない方は 話している最初の10~15分程度でサンプルのカウンターアプリの起動 まで準備していただけますと スムーズに進行できるかと思いますので、ご協力お願いします。 それではよろしくお願いします。 pregum 3

4.

Todo アプリ ハンズオン 動作環境 のバージョン: 3.0.5 Flutter のバージョンは flutter doctor -v で確認できます。 Flutter のバージョンをいじりたくない場合は fvm を入れてバージョンを固定しましょう . brew install fvm コマンド実行後、今回の作業フォルダで fvm local 3.0.5 -f を実行すれば OK 参考サイト: https://zenn.dev/riscait/articles/flutter-versionFlutter management pregum 4

5.

Todo アプリ ハンズオン 自己紹介 年生まれ 普段はKotlin, Swift, TypeScript で開発しています Flutter で個人アプリを 作っています 1995 pregum 5

6.

Todo アプリ ハンズオン Flutter とは? が開発中のクロスプラットフォーム(以降XP)開発が可能なフ レームワークです。 今現在(2022/8/22)、iOS/Android/Web/Linux/macOS/Windowが 開発可能です。 Google pregum 6

7.

Todo アプリ ハンズオン Flutter とネイティブアプリとの違い 開発スピードと処理速度 項目 Flutter パフォーマンス 若干遅い 開発速度 概ね1Platform分 検討されるケース 開発コスト削減 pregum ネイティブアプリ 早い OS 数に応じて遅くなる native の機能が必要 7

8.

Todo アプリ ハンズオン なぜ他のXPではなくFlutterなのか? 色々ありますが以下が大きな要因です。 いい感じのUIが標準ライブラリで作れる アプリを起動しながらレイアウトの微調整が可能 Debug ツールが使いやすい 対応プラットフォームが多い UI のソースが Web 上で共有できる (DartPad) pregum 8

9.

Todo アプリ ハンズオン なぜ他のXPではなくFlutterなのか? --> UI のソースがWeb上で共有できる(DartPad) 下記のurlからサンプルコードが実行可能 https://dartpad.dev/7942cc454f0937046632c7c61ea3e773 pregum 9

10.

Todo アプリ ハンズオン 実行結果 pregum 10

11.

Todo アプリ ハンズオン 開発も全てDartPadで良いのでは 端末上では確認できない 複数ファイル必要な複雑なレイアウトは確認できない MySQL などの DB や端末のセンサを使用するライブラリは使用不可 上記の点で実際の開発環境として使うのは厳しい 軽く挙動を見たい時に使うのが良さそう pregum 11

12.

Todo アプリ ハンズオン 今日作るアプリについて pregum 12

13.

Todo アプリ ハンズオン 今日作るアプリについて 今日できるアプリ https://github.com/Pregum/todo-app-hands-on-flutter 機能一覧 タスク作成機能 タスク編集機能 タスク削除機能 タスク完了チェック機能 pregum 13

14.

Todo アプリ ハンズオン アプリを作り始める前に Flutter のUIについて のUIは全てウィジェット テキスト ボタン チェックボックス Flutter etc... pregum 14

15.

Todo アプリ ハンズオン Flutter のUIについて ウィジェットは大きく分けて2種類存在する 状態(State)を持つStateful Widget setState() で状態を変更可能 状態(State)を持たないStateless Widget setState() は使用不可 親ウィジェットや外部から受け取るデータによって更新可能 最初はStateful Widgetを使っておけばOK pregum 15

16.
[beta]
Todo

アプリ ハンズオン

Flutter

は宣言的UI

宣言的UI (React, SwiftUI, etc...)
String name = 'taro';
Center(
child: Text('Hello $name'),
),
// -> Hello taro

命令的UI (UIKit, WinForms, etc...)
text.frame = CGRect(
x: 50,
y: 50,
width: 50,
height: 50
)
text.text = "taro"
text.textAlignment = NSTextAlignment.Center

何を表示させるかを記述する。 レイアウトの配置からテキストの
文字列まで記述する。
pregum

16

17.

Todo アプリ ハンズオン 一言で表すと 宣言的UIは何をしたいかをコードで伝える (What) 命令的UIはどのようにしたいかをコードで伝える (How) pregum 17

18.

Todo アプリ ハンズオン Flutter での描画 どのウィジェットを使用する場合でもレイアウトは build メソッドに 記述されています。 Text, ListView, Slider, Container, etc... build build どのウィジェットでも メソッドに記載されています。 レイアウトを確認したいときは で検索すると良いです。 pregum 18

19.

Todo アプリ ハンズオン 【注意】画面の更新にはルールが存在する 画面の更新処理は必ず setState() メソッドの中に記述すること OK // : Text(count) // : ヨシ! // setState(() { count = count + 1; }); pregum NG // : Text(count) // : これでは画面に された値が反映されない // +1 count = count + 1; 19

20.

Todo アプリ ハンズオン Todo アプリで使う主なウィジェット MaterialApp 根本にとりあえず置いておくウィジェット Scaffold 画面の大枠を作ってくれるウィジェット ListView いい感じにリスト形式で表示してくれる便利なウィジェット Container pregum 十徳ナイフのような万能ウィジェット 20

21.

Todo アプリ ハンズオン 作成の流れ プロジェクト作成 2. サンプルアプリ ( カウンターアプリ ) 動作確認 3. 1 つのタスクの UI 作成 4. リスト形式に並べる UI を作成 5. main.dart への配置 1. pregum 21

22.

Todo アプリ ハンズオン プロジェクト作成 で新規プロジェクトを作成します。 プロジェクト名は何でも大丈夫です。 特になければ hands_on_todo_app でお願いします。 VS Code pregum 22

23.

Todo アプリ ハンズオン サンプル(カウンターアプリ)動作確認 作成したプロジェクトをAndroid エミュレータで動かしてみます。 ここではVS Codeを使用します。 main.dart を VSCode 上で選択後、起動先エミュレータを設定します。 その後、F5で無事起動すればOK pregum 23

24.

Todo アプリ ハンズオン 1 つのタスクUI作成 TodoTileWidget クラスの作成 ファイルを作成し、 クラスを作成します。 todo_tile_widget.dart TodoTileWidget ファイル内に class TodoTileWidget extends StatefulWidget { // : } class _TodoTileWidgetState extends State<TodoTileWidget> { // : } pregum 24

25.

Todo アプリ ハンズオン 1 つのタスクUI作成 Hive プラグインのインポート pubspec.yaml dependencies ファイルの に下記ライブラリを記載し、保存します。 dependencies: // : hive: 2.2.3 uuid: 3.0.6 intl: 0.17.0 hive_flutter: 1.1.0 インデントがずれているとうまく読み込めないのでご注意下さい。 ※ pregum 25

26.

Todo アプリ ハンズオン 1 つのタスクUI作成 Hive の開発関連のプラグインをインポート ファイルの に下記ライブラリを記載し、保存します。 pubspec.yaml dev_dependencies dev_dependencies: // : hive_generator: 1.1.3 build_runner: 2.2.0 ※ インデントがずれているとうまく読み込めないのでご注意下さい。 pregum 26

27.

Todo アプリ ハンズオン 1 つのタスクUI作成 ファイルを配置 共有しましたフォルダ内のファイルを lib フォルダ直下へ配置します。 pregum 27

28.
[beta]
Todo

アプリ ハンズオン

1

つのタスクUI作成

引数にTodoクラスのオブジェクトを設定
TodoTileWidget

クラスの引数に MyTodo クラスの引数を追加します。

class TodoTileWidget extends StatefulWidget {
final MyTodo todo;
const TodoTileWidget({ Key? key, required this.todo, })
: super(key: key);
}
class _TodoTileWidgetState extends State<TodoTileWidget> {
//
widget.todo
}

使うときは

pregum

でアクセス可能

28

29.
[beta]
Todo

アプリ ハンズオン

1

つのタスクUI作成

Tile

ウィジェットを作成
の

メソッドに
の順でウィジェットを配置

TodoTileWidget
build
Card > CheckboxListTile > Text

Widget build(BuildContext context) {
return Card(
child: CheckboxListTile(
value: widget.todo.isCompleted, // check
onChanged: (bool? newValue) { }, //
ON/OFF
title: Text( widget.todo.taskName ), //
subtitle: Text('
: ${ widget.todo.updatedAt }'), //
)
);
pregum
}

更新日

用の変数を設定
チェックの
時のコールバックを設定
タスク名を設定
更新日を設定
29

30.

Todo アプリ ハンズオン 1 つのタスクUI作成 未チェック/チェック済 変数の設定 先ほどの CheckboxListTile の onChanged プロパティに 未チェック/チェック済の切り替え時に実行される処理を記述します。 child: CheckboxListTile( // : onChanged: (bool? newValue) async { if (newValue == null) { return; } widget.todo.isCompleted = newValue; // await MyTodoManager.instance.updateTodo(widget.todo); } // : ) これだけだと画面に反映されない (・x・) pregum 30

31.

Todo アプリ ハンズオン 1 つのタスクUI作成 完了時に取り消し線をつける処理を追加 の title プロパティ に取り消し線の処理を追加します。 CheckboxListTile child: CheckboxListTile( // : title: Text( widget.doto.taskName, style: widget.todo.isCompleted ? const TextStyle(decoration: TextDecoration.lineThrough) // : null, // ), // : ) 未完了時は取り消し線無し pregum 完了時は取り消し線有り 31

32.
[beta]
Todo

アプリ ハンズオン

1

つのタスクUI作成

編集と削除用コールバックを引数に追加
TodoTileWidget

クラスに編集と削除用のコールバックを追加します。

class TodoTileWidget extends StatefulWidget {
final MyTodo todo;
final Function()? onDismiss; //
final Function()? onLongTap; //
const TodoTileWidget({
Key? key,
required this.todo,
this.onDismiss, //
-this.onLongTap, //
-}) : super(key: key);

削除用コールバック -- 追加した行
編集用コールバック -- 追加した行

削除用コールバック
編集用コールバック

pregum

追加した行
追加した行
32

33.

Todo アプリ ハンズオン 1 つのタスクUI作成 編集と削除用コールバックを引数に追加 の メソッドに配置した Card ウィジェットを ウィジェットで包みます。 TodoTileWidget build MyTodoTileWrapper Widget build(BuildContext context) { return MyTodoTileWrapper( todo: widget.todo, onDismiss: () { widget.onDismiss?.call(); }, onLongTap: () { widget.onLongTap?.call(); }, child: Card( // : pregum 33

34.

Todo アプリ ハンズオン リスト形式のUIを作成 todo_page.dart ファイルの作成 フォルダ直下に todo_page.dart ファイルを作成します。 todo_page.dart ファイル内に TodoPage クラスを作成します。 lib class TodoPage extends StatefulWidget { // : } class _TodoPageState extends State<TodoPage> { // : } pregum 34

35.

Todo アプリ ハンズオン リスト形式のUIを作成 MyUtils mixin _TodoPageState の追加 クラスに MyUtils mixinを適用します。 class _TodoPageState extends State<TodoPage> with MyUtils { // : これで、 showDeletedTodoSnackBar , showEditingTodoDialog などが使え るようになります。 ※ 追加後、 my_utils.dart ファイルインポートを忘れないように してください。 pregum 35

36.

Todo アプリ ハンズオン リスト形式のUIを作成 TodoTileWidget ウィジェットを配置 先ほど作成した TodoPage クラスの build メソッドに TodoTileWidget ウィジェットを配置します。 @override Widget build(BuildContext context) { final todo = MyTodo(id: 'test', taskName: ' return TodoTileWidget(todo: todo); } pregum タスク1', isCompleted: false); 36

37.

Todo アプリ ハンズオン リスト形式のUIを作成 TodoTileWidget TodoTileWidget のonDissmissとonLongTapの設定 の onDissmiss と onLongTap を記述します。 return TodoTileWidget( todo: todo, onDismiss: () async { await MyTodoManager.instance.deleteTodo(todo); showDeletedTodoSnackBar(context, todo, index); }, onLongTap: () async { await showEditingTodoDialog(context, todo, newItem: false); }, ); pregum 37

38.

Todo アプリ ハンズオン リスト形式のUIを作成 ListView ウィジェットを追加 先ほど配置した TodoTileWidget を ListView ウィジェットで包みます。 Widget build(BuildContext context) { final todo = MyTodo(id: 'test', taskName: ' final todos = [todo]; return ListView.builder( itemCount: todos.length, itemBuilder: (context, index) { final todo = todos[index]; return TodoTileWidget( // : pregum タスク1', isCompleted: false); 38

39.

Todo アプリ ハンズオン リスト形式のUIを作成 MyLoadingTodoWidget の配置 先ほど配置した ListView を MyLoadingTodoWidget で包みます。 Widget build(BuildContext context) { return MyLoadingTodoWidget( builder: ((todos) { return ListView.builder( // : }), ); ListView pregum のreturnと仮で作成していたtodo, todosは削除します。 39

40.

Todo アプリ ハンズオン main.dart hive への配置 にMyTodoのアダプタクラスを登録 main.dart ファイルの main メソッド内を下記のように書き換えます。 Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await Hive.initFlutter(); Hive.registerAdapter(MyTodoAdapter()); } pregum runApp(const MyApp()); 40

41.

Todo アプリ ハンズオン main.dart への配置 _MyHomePageState _MyHomePageState す。 にTodoPageを配置 クラスの build メソッド内に TodoPage を配置しま Widget build(BuildContext context) { return Scaffold( // : body: const TodoPage(), // : pregum 41

42.

Todo アプリ ハンズオン main.dart への配置 _MyHomePageState にFABの処理を設定 を配置したその下の floatingActionButton.onPressd の処理を 書き換えます。 TodoPage // : body: const TodoPage(), floatingActionButton: FloatingActionButton( onPressed: () async { await MyTodoManager.instance.createNewTodo(); }, ), // : pregum 42

43.

Todo アプリ ハンズオン 完成 お疲れ様でした pregum 43

44.

Todo アプリ ハンズオン 改善ヒント 更新時、特定のtodoタスクのみ更新させる 状態管理ライブラリを使用してコード量を減らす 完了todoタスクを非表示にする機能の追加 todo タスクの順番を入れ替える機能の追加 pregum 44

45.

Todo アプリ ハンズオン 参考サイト https://twitter.com/gethackteam/status/1268892357027663873? ref_src=twsrc^tfw|twcamp^tweetembed|twterm^126889235702 7663873|twgr^12007820d2fc3fecbe0ca6381183ab580763b432| twcon^s1_&ref_url=https%3A%2F%2Fqiita.com%2FHiroyuki_OSA KI%2Fitems%2Ff3f88ae535550e95389d https://qiita.com/Hiroyuki_OSAKI/items/f3f88ae535550e95389d https://ui.dev/imperative-vs-declarative-programming pregum 45