はじめに
前回は状態管理の方法について学びました。

今回は、Flutterを使ったシンプルなTodoアプリの設計と実装を行います。Todoアプリは、アプリ開発の基本的な部分を学ぶのに最適なプロジェクトであり、一覧表示やデータの追加、削除といった操作が含まれるため、アプリケーションの基本的な構造を理解するのに役立ちます。
このプロジェクトでは、Flutterの代表的なウィジェットを使いながら、実際のアプリを作成し、CRUD機能(作成、読み込み、更新、削除)の実装を学びます。初めてのFlutterアプリとして、ぜひ一緒に作っていきましょう。
Todoアプリの画面設計
Todoアプリの基本機能には、タスクの一覧表示、タスクの追加、タスクの削除があります。これらを実現するために、Flutterの以下のUI要素を使います。
使うUI要素
- Scaffold: アプリの基盤となるレイアウト
- AppBar: 上部のバー(タイトルなどを表示)
- FloatingActionButton: 画面の下部に配置されるアクションボタン
- ListTile: タスクの各項目を表示
- TextField: タスクを入力するテキスト入力欄
完成イメージ
- AppBarにはアプリのタイトルを表示し、FloatingActionButtonを押すと、新しいTodoを追加できるようにします。
- ListTileを使って、Todoリストを表示し、更新、削除操作を簡単に行えるようにします。

アプリの設計
最初に、アプリ全体の設計を行います。main()
関数では、Flutterアプリを起動するために runApp()
を呼び出しています。この関数によって、アプリ全体が実行されます。TodoListScreen
というウィジェットがアプリのメイン画面(ホーム画面)として表示されます。
import 'package:flutter/material.dart';
void main() {
runApp(TodoApp());
}
class TodoApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Todo App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: TodoListScreen(),
);
}
}
Todoリストの基本画面
次に、Todoリストの基本的な画面を設計します。リストにタスクを表示するためにListView
とListTile
を使い、ユーザーがタスクを追加できるようにします。
タスクリストの状態を管理するためにStatefulWidget
を利用します。
TodoリストのUI
class TodoListScreen extends StatefulWidget {
@override
_TodoListScreenState createState() => _TodoListScreenState();
}
class _TodoListScreenState extends State<TodoListScreen> {
List<String> _todoItems = []; // Todoアイテムを保持するリスト
// 新しいタスクを入力するダイアログを表示する
void _promptAddTodoItem() {
showDialog(
context: context,
builder: (BuildContext context) {
TextEditingController _textFieldController = TextEditingController();
return AlertDialog(
title: Text('Add a new task'),
content: TextField(
controller: _textFieldController,
decoration: InputDecoration(hintText: 'Enter task here'),
),
actions: <Widget>[
TextButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop(); // ダイアログを閉じる
},
),
TextButton(
child: Text('Add'),
onPressed: () {
_addTodoItem(_textFieldController.text); // アイテムを追加(後で実装)
Navigator.of(context).pop(); // ダイアログを閉じる
},
),
],
);
},
);
}
// 既存のタスクを編集するダイアログを表示する
void _promptEditTodoItem(int index) {
showDialog(
context: context,
builder: (BuildContext context) {
TextEditingController _textFieldController = TextEditingController();
_textFieldController.text = _todoItems[index]; // 現在のタスクをテキストフィールドに表示
return AlertDialog(
title: Text('Edit task'),
content: TextField(
controller: _textFieldController,
decoration: InputDecoration(hintText: 'Edit task here'),
),
actions: <Widget>[
TextButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop(); // ダイアログを閉じる
},
),
TextButton(
child: Text('Save'),
onPressed: () {
_editTodoItem(index, _textFieldController.text);// アイテムを更新(後で実装)
Navigator.of(context).pop(); // ダイアログを閉じる
},
),
],
);
},
);
}
// Todoリストを表示するメソッド
Widget _buildTodoList() {
return ListView.builder(
itemCount: _todoItems.length,
itemBuilder: (context, index) {
return _buildTodoItem(_todoItems[index], index);
},
);
}
// 各Todoアイテムを表示するメソッド
Widget _buildTodoItem(String todoText, int index) {
return ListTile(
title: Text(todoText),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => _removeTodoItem(index), // アイテムを削除(後で実装)
),
onTap: () => _promptEditTodoItem(index), // アイテムをタップして編集
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Todo List'),
),
body: _buildTodoList(), // Todoリストを表示
floatingActionButton: FloatingActionButton(
onPressed: _promptAddTodoItem, // 新しいタスクを追加するダイアログを表示
child: Icon(Icons.add),
),
);
}
}
説明
- _todoItems:Todoリストを格納するリストです。
setState()
を使ってリストの内容を変更し、UIに反映させます。 - _addTodoItem():新しいタスクをリストに追加するメソッドです。入力したタスクが空でない場合のみ追加します。
- _removeTodoItem():タスクを削除するメソッドです。リストの指定されたインデックスにあるタスクを削除します。
- _promptAddTodoItem():タスクを入力するためのダイアログを表示します。このダイアログでタスクを入力し、「Add」ボタンを押すとリストにタスクが追加されます。
- _promptEditTodoItem():タスクを更新するためのダイアログを表示します。テキストフィールドには登録しているタスクが表示されます。このダイアログでタスクを入力し、「save」ボタンを押すとリストの対象タスクが更新されます。
- _buildTodoList():
ListView.builder
を使ってリスト内のアイテムを動的に生成し、表示します。 - _buildTodoItem():各タスクを
ListTile
として表示し、右側に削除ボタンを付けています。
CRUD機能の実装
CRUDとは、Create(作成)、Read(読み込み)、Update(更新)、Delete(削除)の略で、データを扱う基本的な操作のことです。このTodoアプリでは、CRUD機能をシンプルに実装していきます。
作成(Create)
新しいTodoを作成するには、FloatingActionButtonを押してダイアログを表示し、タスクを入力します。_addTodoItem()
メソッドでタスクをリストに追加します。
void _addTodoItem(String task) {
if (task.isNotEmpty) {
setState(() {
_todoItems.add(task);
});
}
}
読み込み(Read)
作成されたタスクは_buildTodoList()
で読み込み、ListView.builder
を使ってリスト表示しています。これにより、複数のTodoアイテムがリストに表示されます。
Widget _buildTodoList() {
return ListView.builder(
itemCount: _todoItems.length,
itemBuilder: (context, index) {
return _buildTodoItem(_todoItems[index], index);
},
);
}
更新(Update)
ListTile
をタップすると編集用のダイアログを表示し、ユーザーがタスクを編集することで、更新機能を追加できます。
void _editTodoItem(int index, String newTask) {
if (newTask.isNotEmpty) {
setState(() {
_todoItems[index] = newTask;
});
}
}
4. 削除(Delete)
リスト内のタスクを削除するためには、ListTile
に削除ボタン(IconButton
)を追加し、ユーザーがそれを押すことでタスクが削除されます。
void _removeTodoItem(int index) {
setState(() {
_todoItems.removeAt(index);
});
}
完成コード
import 'package:flutter/material.dart';
void main() {
runApp(TodoApp());
}
class TodoApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Todo App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: TodoListScreen(),
);
}
}
class TodoListScreen extends StatefulWidget {
@override
_TodoListScreenState createState() => _TodoListScreenState();
}
class _TodoListScreenState extends State<TodoListScreen> {
List<String> _todoItems = []; // Todoアイテムを保持するリスト
// Todoアイテムを追加するメソッド
void _addTodoItem(String task) {
if (task.isNotEmpty) {
setState(() {
_todoItems.add(task); // 新しいタスクをリストに追加
});
}
}
// Todoアイテムを編集するメソッド
void _editTodoItem(int index, String newTask) {
if (newTask.isNotEmpty) {
setState(() {
_todoItems[index] = newTask; // タスクを更新
});
}
}
// Todoアイテムを削除するメソッド
void _removeTodoItem(int index) {
setState(() {
_todoItems.removeAt(index); // 指定されたインデックスのアイテムを削除
});
}
// 新しいタスクを入力するダイアログを表示する
void _promptAddTodoItem() {
showDialog(
context: context,
builder: (BuildContext context) {
TextEditingController _textFieldController = TextEditingController();
return AlertDialog(
title: Text('Add a new task'),
content: TextField(
controller: _textFieldController,
decoration: InputDecoration(hintText: 'Enter task here'),
),
actions: <Widget>[
TextButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop(); // ダイアログを閉じる
},
),
TextButton(
child: Text('Add'),
onPressed: () {
_addTodoItem(_textFieldController.text);
Navigator.of(context).pop(); // ダイアログを閉じる
},
),
],
);
},
);
}
// 既存のタスクを編集するダイアログを表示する
void _promptEditTodoItem(int index) {
showDialog(
context: context,
builder: (BuildContext context) {
TextEditingController _textFieldController = TextEditingController();
_textFieldController.text = _todoItems[index]; // 現在のタスクをテキストフィールドに表示
return AlertDialog(
title: Text('Edit task'),
content: TextField(
controller: _textFieldController,
decoration: InputDecoration(hintText: 'Edit task here'),
),
actions: <Widget>[
TextButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop(); // ダイアログを閉じる
},
),
TextButton(
child: Text('Save'),
onPressed: () {
_editTodoItem(index, _textFieldController.text);
Navigator.of(context).pop(); // ダイアログを閉じる
},
),
],
);
},
);
}
// Todoリストを表示するメソッド
Widget _buildTodoList() {
return ListView.builder(
itemCount: _todoItems.length,
itemBuilder: (context, index) {
return _buildTodoItem(_todoItems[index], index);
},
);
}
// 各Todoアイテムを表示するメソッド
Widget _buildTodoItem(String todoText, int index) {
return ListTile(
title: Text(todoText),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => _removeTodoItem(index), // アイテムを削除
),
onTap: () => _promptEditTodoItem(index), // アイテムをタップして編集
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Todo List'),
),
body: _buildTodoList(), // Todoリストを表示
floatingActionButton: FloatingActionButton(
onPressed: _promptAddTodoItem, // 新しいタスクを追加するダイアログを表示
child: Icon(Icons.add),
),
);
}
}
まとめ
今回のチュートリアルでは、Flutterを使ってシンプルなTodoアプリを作成しました。このアプリを通して、状態管理やCRUD機能の実装、リスト表示といった基本的な概念を学びました。今回のTodoアプリをベースに、機能を追加したり、デザインをカスタマイズすることで、より複雑なアプリの開発に挑戦してみてください。
この記事のポイント
StatefulWidget
を使ってTodoアプリの状態管理を実装ListView
やListTile
を使ったタスクの一覧表示FloatingActionButton
で新しいタスクの追加を実現- CRUD操作(作成、読み込み、更新、削除)をシンプルに実装
次回は、このアプリにさらに機能を追加して、例えばローカルデータベースへのデータ保存の方法について学んでいきます。
第6回はこちら

コメント