15
10

More than 3 years have passed since last update.

【Flutter】SharedPreferencesでListデータを保存する方法【図解付き】

Last updated at Posted at 2020-08-30

こんな方におすすめの記事です。

  • 端末にデータ保存できるSharedPreferencesの使い方はある程度理解している
  • List形式のデータを保存したい

SharedPreferencesはList形式のデータを保存したい場合、String型しか保存できません。

あらゆる型を持つListデータを保存したい場合は、ひと手間必要です。

解決策:json形式を活用

json形式のエンコードとデコードを行うことで実現できます。
僕のアプリ製作実践例よりお伝えします。

Providerの使い方はこちら。

【Flutter】アプリ製作から学ぶProviderの使い方【図解付き】

(下準備)Map関連処理を作成

下記のClockModelは、

  • Map型への変換 ※保存の際に使用
  • Mapオブジェクトを代入する処理 ※読み出しの際に使用

のための下準備です。
後で使用します。

clock.dart
class ClockModel {
  final String id;
  String clock;
  int currentSeconds;
  int plusSeconds;
  bool isMyTurn = false;
  Timer timer;

  ClockModel(
      {this.id,
      this.clock,
      this.currentSeconds,
      this.plusSeconds,
      this.isMyTurn,
      this.timer});

  /// Map型に変換
  Map toJson() => {
        'id': id,
        'clock': clock,
        'currentSeconds': currentSeconds,
        'plusSeconds': plusSeconds,
        'isMyTurn': isMyTurn,
        'timer': timer,
      };

  /// JSONオブジェクトを代入
  ClockModel.fromJson(Map json)
      : id = json['id'],
        clock = json['clock'],
        currentSeconds = json['currentSeconds'],
        plusSeconds = json['plusSeconds'],
        isMyTurn = json['isMyTurn'],
        timer = json['timer'];
}

SharedPreferences Listデータ保存方法

  1. Map形式に変換
  2. Json形式に変換(エンコード)
  3. String型のリストに変換
  4. setStringListで保存

図で表すとご覧のとおり(正確ではないです)。
Flutter-SharedPreferences保存 (2).png
※アイコンは、自ブログ( https://koaramarch.com )で使用しているコアラです。

今回は、ClockModelに定義したデータをリスト化した、settingClocksというオブジェクトが保存したいデータです。

clock.dart
class ClockProvider with ChangeNotifier {
  // 今回保存したいリスト
  List<ClockModel> settingClocks = [];

  ClockProvider() {
    syncDataWithProvider();
  }

  void initSettingClocks() {
    settingClocks = [
      ClockModel(
          id: '1',
          clock: '00:05:00',
          currentSeconds: 300,
          plusSeconds: 5,
          isMyTurn: false),
      ClockModel(
          id: '2',
          clock: '00:05:00',
          currentSeconds: 300,
          plusSeconds: 5,
          isMyTurn: false),
    ];
  }

  void setInitialSharedPrefrences() {
    // 設定初期化
    initSettingClocks();
    // sharedPreferencesに保存
    updateSharedPrefrences();
  }

  /// SharedPrefrences保存
  Future updateSharedPrefrences() async {
    // ①Map型変換→②Json形式にエンコード→③リスト化
    List<String> myClocks =
        settingClocks.map((f) => json.encode(f.toJson())).toList();

    SharedPreferences prefs = await SharedPreferences.getInstance();
    // ④保存
    await prefs.setStringList('settingClocks', myClocks);

    print('updateSharedPrefrences: $myClocks');

  }
}

asyncで非同期処理化して、SharedPreferencesの処理自体はawaitにして待たせることをお忘れなく。

以下は参考までに、settingClocksへの設定とupdateSharedPrefrences()の呼び出し箇所のコードです。
ボタンタップ時の処理で設定および保存しています。

settingsPage.dart
class SettingsPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () {
        Navigator.pop(context, '戻った');
        return Future.value(false);
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text('設定'),
          actions: [
            FlatButton(
              child: Icon(Icons.refresh),
              onPressed: () {
                Provider.of<ClockProvider>(context, listen: false)
                    .setInitialSharedPrefrences();
              },
            ),
          ],
        ),
        body: SettingsPageHome(),
      ),
    );
  }
}


  void initSettingClocks() {
    settingClocks = [
      ClockModel(
          id: '1',
          clock: '00:05:00',
          currentSeconds: 300,
          plusSeconds: 5,
          isMyTurn: false),
      ClockModel(
          id: '2',
          clock: '00:05:00',
          currentSeconds: 300,
          plusSeconds: 5,
          isMyTurn: false),
    ];
  }

  void setInitialSharedPrefrences() {
    // 設定初期化
    initSettingClocks();
    // sharedPreferencesに保存
    updateSharedPrefrences();
  }

SharedPreferences Listデータ読み出し方法

  1. getStringListで読み出し
  2. Jsonデコード
  3. MapオブジェクトをClockModelに代入
  4. リストに変換

図で表すとご覧のとおり(こちらもあくまでイメージです)。
Flutter-SharedPreferences読み出し (2).png

保存処理の逆からたどる感じですね。
コードは以下のとおり。

clock.dart
/// SharedPrefrences読み出し
  Future syncDataWithProvider() async {
    print('syncDataWithProvider');

    SharedPreferences prefs = await SharedPreferences.getInstance();
    // ①読み出し
    var result = prefs.getStringList('settingClocks');

    print('result:$result');

    // 読み出し確認
    if (result != null) {
      // ②デコード→③MapオブジェクトをClockModelに代入→④リストに変換
      settingClocks =
          result.map((f) => ClockModel.fromJson(json.decode(f))).toList();
    } else {
      // 必要に応じて初期化
    }

  }

以下は参考までに、読み出し処理の実行箇所です。
ClockProviderのコンストラクタにて読み出しています。

clock.dart
class ClockProvider with ChangeNotifier {
  List<ClockModel> settingClocks = [];

  ClockProvider() {
    syncDataWithProvider();
  }
}

SharedPreferencesでリストを保存する際にお役に立ちますと幸いです。

参考

15
10
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
15
10