やりたいこと
下記のようなフォームにて、データ入力後に保存ボタンを押下します。
その後アプリを再ビルドした際に値を表示させたいです。
環境
- MacOS Monterey 12.4
- Android Studio
- Flutter 3.0.3
- Dart 2.17.6
実装方法
インストール
pubspec.yamlに下記のように行を追加します。
pubspec.yaml
dependencies:
shared_preferences: ^2.0.15
パッケージのインポート
main.dartに追加します。
main.dart
import 'package:shared_preferences/shared_preferences.dart';
入力フォームを作成する
保存ボタンも実装します。
main.dart
body: Center(
child: Column(
children: [
Container(
margin: const EdgeInsets.only(top: 30, left: 30, right: 30),
child: TextField(
onChanged: setTeamName,
style: TextStyle(fontSize: 30),
decoration: InputDecoration(
labelText: "チーム名",
hintText: "入力してください",
suffixIcon: IconButton(
padding: const EdgeInsets.only(top: 40),
onPressed: () {
valueController.clear(); //リセット処理
setTeamName(''); //空文字をセット
},
icon: Icon(Icons.clear),
),
),
controller: valueController,
),
),
Container(
margin: const EdgeInsets.only(top: 40),
child: SizedBox(
width: 150,
height: 50,
child: ElevatedButton(
child: const Text('保存'),
style: ElevatedButton.styleFrom(
primary: Colors.orange,
onPrimary: Colors.white,
),
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
duration: const Duration(seconds: 5),
content: Text('保存しました'),
action: SnackBarAction(
label: '閉じる',
onPressed: () {},
),
),
);
debugPrint(teamName);
},
),
)),
],
),
),
保存/読み込みのメソッドを作成する
shared_preferencesではキーと値を紐づけて保存できます。
main.dart
class _MyHomePageState extends State<MyHomePage> {
final valueController = TextEditingController();
static const keyTeamName = 'teamName';
String teamName = '';
void setTeamName(String a) {
setState(() {
teamName = a;
});
}
@override
void initState() {
super.initState();
Future(() async {
await _getData();
});
}
//保存
Future<void> _setData() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(keyTeamName, teamName);
}
//読み込み
Future<void> _getData() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
teamName = prefs.getString(keyTeamName) ?? ''; //キーに紐付けた値を変数に代入
valueController.text = teamName; //保存した値を初期値として表示
debugPrint(teamName);
});
}
画面構築時に_getDataする
initStateを使います。
main.dart
@override
void initState() {
super.initState();
Future(() async {
await _getData();
});
}
実際の動作
shared_preferencesを使わない場合
入力後、再ビルドすると値は消えてしまいます。
shared_preferencesを使った場合
再ビルドした後も、値は表示(=保存)されています。
※GIFを直接貼れなかったのでリンクから飛んでくださいm(__)m
おわりに
今回はshared_preferencesを学習しました。アプリを落としても値が保存されることで再入力の手間が省け、使いやすさに繋がると思いました!
ここにページ間での値の受け渡しなどが入ってくると、難易度が上がるなと個人的には感じました。
この記事が参考になると嬉しいです( ̄▽ ̄)
コード全文
main.dart
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final valueController = TextEditingController();
static const keyTeamName = 'teamName';
String teamName = '';
void setTeamName(String a) {
setState(() {
teamName = a;
});
}
@override
void initState() {
super.initState();
Future(() async {
await _getData();
});
}
//保存
Future<void> _setData() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(keyTeamName, teamName);
}
//読み込み
Future<void> _getData() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
teamName = prefs.getString(keyTeamName) ?? ''; //キーに紐付けた値を変数に代入
valueController.text = teamName; //保存した値を初期値として表示
debugPrint(teamName);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("入力フォーム"),
centerTitle: true,
),
body: Center(
child: Column(
children: [
Container(
margin: const EdgeInsets.only(top: 30, left: 30, right: 30),
child: TextField(
onChanged: setTeamName,
style: TextStyle(fontSize: 30),
decoration: InputDecoration(
labelText: "チーム名",
hintText: "入力してください",
suffixIcon: IconButton(
padding: const EdgeInsets.only(top: 40),
onPressed: () {
valueController.clear(); //リセット処理
setTeamName(''); //空文字をセット
},
icon: Icon(Icons.clear),
),
),
controller: valueController,
),
),
Container(
margin: const EdgeInsets.only(top: 40),
child: SizedBox(
width: 150,
height: 50,
child: ElevatedButton(
child: const Text('保存'),
style: ElevatedButton.styleFrom(
primary: Colors.orange,
onPrimary: Colors.white,
),
onPressed: () {
_setData();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
duration: const Duration(seconds: 5),
content: Text('保存しました'),
action: SnackBarAction(
label: '閉じる',
onPressed: () {},
),
),
);
debugPrint(teamName);
},
),
)),
],
),
),
);
}
}