1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Flutter】shared_preferencesを使って値を保存したい

Last updated at Posted at 2022-07-26

やりたいこと

下記のようなフォームにて、データ入力後に保存ボタンを押下します。
その後アプリを再ビルドした際に値を表示させたいです。
スクリーンショット 2022-07-26 15.26.55.png

環境

  • 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);
                    },
                  ),
                )),          
          ],
        ),
      ),
    );
  }
}

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?