はじめに
前回はToDoリストを作成しました。

しかしこのままではアプリを起動するたびにデータが消えてしまいます。
そこで今回はローカルデータの保存について学びます。
アプリケーション開発をしていると、ローカルデータの保存は重要な機能のひとつです。たとえば、アプリを終了した後でも、ユーザーの設定やデータを保持したい場合、ローカルにデータを保存する仕組みが必要になります。Flutterでは、shared_preferencesパッケージを使うことで、簡単にデータを端末に保存し、アプリを再起動してもデータを保持することができます。
この記事では、shared_preferencesを使ってデータをローカルに保存する方法を解説し、これを使ってTodoアプリにデータの永続化を実装します。
shared_preferencesパッケージのインストール
まずは、shared_preferencesパッケージをプロジェクトにインストールします。これは、Flutterの公式ライブラリであり、簡単にローカルデータを保存・読み込みできる仕組みを提供します。
パッケージのインストール
pubspec.yaml
ファイルにshared_preferences
を追加します。
dependencies:
flutter:
sdk: flutter
shared_preferences: ^2.0.6
追加後、以下のコマンドを実行してインストールします。
flutter pub get
これで、shared_preferencesパッケージがプロジェクトに追加され、使用できるようになりました。
shared_preferencesの基本的な使い方
shared_preferencesは、基本的にキーと値のペアでデータを保存します。数値や文字列、ブール値、リストなどの簡単なデータ型を保存することができます。
データの保存
shared_preferencesにデータを保存するには、次のコードを使います。
import 'package:shared_preferences/shared_preferences.dart';
Future<void> saveData(String key, String value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(key, value);
}
setString
メソッドで、文字列データを保存しています。数値の場合はsetInt
、ブール値の場合はsetBool
など、データ型に応じたメソッドが用意されています。
データの読み込み
保存したデータを読み込む方法は以下の通りです。
Future<String?> loadData(String key) async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString(key); // キーに対応するデータを取得
}
データを読み込むときは、保存したときと同じキーを使って取得します。
データの削除
保存したデータを削除することもできます。
Future<void> removeData(String key) async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove(key);
}
Todoアプリにデータの永続化を実装
これまでの知識を基に、前回作成したTodoアプリに、shared_preferencesを使ってデータの永続化を追加していきます。これにより、アプリを再起動してもTodoリストが保持されるようになります。
Todoリストの保存と読み込み
まず、Todoリストをshared_preferencesに保存し、アプリ起動時にリストを読み込むようにします。以下は、Todoアイテムを保存・読み込む処理です。
Todoリストの保存
Future<void> _saveTodoList() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setStringList('todo_list', _todoItems);
}
setStringList
を使うことで、Todoアイテムのリストを保存します。
Todoリストの読み込み
Future<void> _loadTodoList() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_todoItems = prefs.getStringList('todo_list') ?? [];
});
}
Todoアプリに保存機能を統合
次に、Todoアプリの保存機能を追加します。以下の例では、Todoリストの追加・削除時に自動的にデータを保存し、アプリ起動時にリストを読み込むようにしています。
アプリ起動時にデータを読み込む
initState
でアプリ起動時に_loadTodoList
を呼び出し、保存されたTodoリストを読み込みます。
@override
void initState() {
super.initState();
_loadTodoList(); // アプリ起動時にデータを読み込む
}
データの追加・更新・削除
Todoリストにタスクを追加・更新・削除した際に、保存するように修正します。
// 追加
void _addTodoItem(String task) {
if (task.isNotEmpty) {
setState(() => _todoItems.add(task));
_saveTodoList();
}
}
// 更新
void _editTodoItem(int index, String newTask) {
if (newTask.isNotEmpty) {
setState(() => _todoItems[index] = newTask);
_saveTodoList();
}
}
// 削除
void _removeTodoItem(int index) {
setState(() => _todoItems.removeAt(index));
_saveTodoList();
}
完成したコード例
以下は、shared_preferencesを使ったTodoアプリの完成版コードです。アプリを終了してもTodoリストが保持され、再起動してもデータが消えないことを確認できます。
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.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 = [];
@override
void initState() {
super.initState();
_loadTodoList();
}
Future<void> _saveTodoList() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setStringList('todo_list', _todoItems);
}
Future<void> _loadTodoList() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_todoItems = prefs.getStringList('todo_list') ?? [];
});
}
void _addTodoItem(String task) {
if (task.isNotEmpty) {
setState(() => _todoItems.add(task));
_saveTodoList();
}
}
void _removeTodoItem(int index) {
setState(() => _todoItems.removeAt(index));
_saveTodoList();
}
void _editTodoItem(int index, String newTask) {
if (newTask.isNotEmpty) {
setState(() => _todoItems[index] = newTask);
_saveTodoList();
}
}
void _promptAddTodoItem() {
TextEditingController _textFieldController = TextEditingController();
showDialog(
context: context,
builder: (BuildContext context) {
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) {
TextEditingController _textFieldController = TextEditingController();
_textFieldController.text = _todoItems[index];
showDialog(
context: context,
builder: (BuildContext context) {
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();
},
),
],
);
},
);
}
Widget _buildTodoList() {
return ListView.builder(
itemCount: _todoItems.length,
itemBuilder: (context, index) {
return _buildTodoItem(_todoItems[index], index);
},
);
}
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(),
floatingActionButton: FloatingActionButton(
onPressed: _promptAddTodoItem,
child: Icon(Icons.add),
),
);
}
}
まとめ
この記事では、shared_preferencesを使ってデータをローカルに保存し、アプリを再起動してもTodoリストが保持される仕組みを実装しました。shared_preferencesは、設定や小さなデータを保存するために非常に便利な方法です。
この記事のポイント
- shared_preferencesを使ったローカルデータの保存方法を学習。
- データの保存、読み込み、削除方法を理解。
- Todoアプリに永続化機能を追加し、アプリを再起動してもデータが保持されるように実装。
次回はテストに関して学びます。
次回はこちら

コメント