質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

1回答

2283閲覧

Fluuter SharedPreferencesでローカル保存

hiro.a

総合スコア28

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2020/10/29 13:06

前提・実現したいこと

SharedPreferencesでローカルで保存したいのですが、保存できるのが最後に入力した文字のみで
入力した文字全て保存されてない

発生している問題・エラーメッセージ

最後に入力した文字しか保存されていない!

該当のソースコード

Flutter

1 2import 'package:flutter/foundation.dart'; 3import 'package:freezed_annotation/freezed_annotation.dart'; 4import 'package:state_notifier/state_notifier.dart'; 5import 'package:todo_app/todo.dart'; 6import 'package:uuid/uuid.dart'; 7import 'package:shared_preferences/shared_preferences.dart'; 8 9// import 'package:cloud_firestore/cloud_firestore.dart'; //cloud_firestoreのインポート 10 11part 'todos_state.freezed.dart'; 12 13//ローディング中を示す 14@freezed 15abstract class TodosState with _$TodosState { 16 const factory TodosState( {//TodosStateのクラスをチェック 17 @Default(<Todo>[]) List<Todo> todos,//すべてのTodoが入るtodos 18 }) = TodosStateData;//TodosStateDataであればデータの読み込みが終わったという判断ができるように 19 const factory TodosState.loading() = TodosStateLoading;//TodosStateLoadingであればまだ読み込み中 20} 21 22//ここにDB 23class TodosController extends StateNotifier<TodosState> with LocatorMixin { //LocatorMixinをmixinする事でcontextにあるproviderへのアクセスを容易する 24 TodosController() : super(const TodosState.loading()); 25 final _uuid = Uuid(); 26 @override 27 void initState() async { 28 super.initState(); 29 await Future<void>.delayed(const Duration(seconds: 3));//initStateで3秒間ウエイトを入れ,初期データとしていくつかのTodoをstateへ設定 30 // 初期データを設定、TodosStateLoadingからTodoStateDataへ変わるのでローディング完了の状態となる 31 32 var prefs = await SharedPreferences.getInstance(); 33 state = TodosState( 34 todos: [ 35 // Todo(id: _uuid.v4(), title: 'テスト'), 36 Todo(id: prefs.getString('_uuid.v4()') , title: prefs.getString('title') ),//書き込む 37 ], 38 ); 39 } 40 41 void add(String title) async {//追加機能 42 final SharedPreferences prefs = await SharedPreferences.getInstance(); 43 final currentState = state; 44 if (currentState is TodosStateData) { 45 // todosのクローンに新しいTodoを追加してstateを更新 46 final todos = currentState.todos.toList() 47 ..add( 48 Todo(id: _uuid.v4(), title: title), 49 ); 50 prefs.setString('id',_uuid.v4());//読み込み 51 prefs.setString('title',title) ; 52 state = currentState.copyWith(//stateはimmutableでメンバ変数を直接変更することはできないので、stateを更新するときは現在のstateからcopyWithでコピーするか、新規のstateで上書きする 53 todos: todos, 54 ); 55 56 } 57 } 58 59 void toggle(Todo todo) { 60 final currentState = state; 61 if (currentState is TodosStateData) { 62 // Todoを検索してcomplatedをtoggleし、stateを更新 63 final todos = currentState.todos.map((t) { 64 if (t == todo) { 65 return t.copyWith( 66 completed: !t.completed, 67 ); 68 } 69 return t; 70 }).toList(); 71 state = TodosState( 72 todos: todos, 73 ); 74 } 75 } 76}

試したこと

補足情報(FW/ツールのバージョンなど)

SQLiteが理解できずにこちらを使うようにしました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

複数のTodoデータを保存したいということでよろしいでしょうか?そうであれば、SharedPreferencesは、キーに対して、上書きすることしかできないので、データを追加するたびに、全体をjsonなどにシリアライズして保存する様にします。

Dart

1import 'package:freezed_annotation/freezed_annotation.dart'; 2 3part 'todo.freezed.dart'; 4part 'todo.g.dart'; 5 6//Todoのモデルを実装 7 8abstract class Todo with _$Todo { 9 //抽象的なクラス。インスタンス化できない 10 11 const factory Todo({ 12 String id, // uuidで割りつける予定 13 String title, 14 (false) bool completed, //@Defaultで初期値を与えるpage=0ではない 15 }) = TodoData; 16 17 factory Todo.fromJson(Map<String, dynamic> json) => _$TodoFromJson(json); 18}

Dart

1 2 void initState() async { 3 super.initState(); 4 await Future<void>.delayed(const Duration(seconds: 3));//initStateで3秒間ウエイトを入れ,初期データとしていくつかのTodoをstateへ設定 5 // 初期データを設定、TodosStateLoadingからTodoStateDataへ変わるのでローディング完了の状態となる 6 7 var prefs = await SharedPreferences.getInstance(); 8 9 final todosJson = prefs.getString('todos'); 10 final todos = json.decode(todosJson).map<Todo>((json) => Todo.fromJson(json)).toList(); 11 12 state = TodosState( 13 todos: todos 14 ); 15 } 16 17 void add(String title) async {//追加機能 18 final SharedPreferences prefs = await SharedPreferences.getInstance(); 19 final currentState = state; 20 if (currentState is TodosStateData) { 21 // todosのクローンに新しいTodoを追加してstateを更新 22 final todos = currentState.todos.toList() 23 ..add( 24 Todo(id: _uuid.v4(), title: title), 25 ); 26 27 final todosJson = json.encode(todos); 28 prefs.setString('todos', todosJson); 29 30 state = currentState.copyWith(//stateはimmutableでメンバ変数を直接変更することはできないので、stateを更新するときは現在のstateからcopyWithでコピーするか、新規のstateで上書きする 31 todos: todos, 32 ); 33 34 } 35 } 36

投稿2020/10/30 04:42

編集2020/11/01 08:18
f-miyu

総合スコア1625

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hiro.a

2020/11/01 06:48

回答いただきありがとうございます。 Todoクラスは以下のように実装しています。 これにJsonで保存するようにすればよろしいでしょうか?
hiro.a

2020/11/01 06:49

import 'package:flutter/foundation.dart'; // *.freezed.dartで必要なのでimportしておく import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:uuid/uuid.dart'; part 'todo.freezed.dart'; //Todoのモデルを実装 @freezed abstract class Todo with _$Todo {//抽象的なクラス。インスタンス化できない const factory Todo({ String id, // uuidで割りつける予定 String title, @Default(false) bool completed, //@Defaultで初期値を与えるpage=0ではない }) = TodoData; }
f-miyu

2020/11/01 08:23

freezedを使っているのなら、pubspec.yamlにjson_serializableを追加して、更新した回答の様にすればいいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問