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

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

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

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

Dart

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

Q&A

解決済

2回答

2076閲覧

データベースの変更をすぐに描画に反映させたい

copp

総合スコア11

Flutter

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

Dart

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

0グッド

0クリップ

投稿2020/06/26 04:30

前提・実現したいこと

SQLを使用してデータを管理し、その内容を画面に表示させたいのですが、
SQLにデータを追加しても(floating buttonで追加しております)画面には反映されず、hot reloadをして始めて反映される状態になっております。

どのように記載すれば、hot reloadしなくても反映されるか御教唆いただけないでしょうか?

よろしくお願い致します

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

hot reloadしないと画面に反映されない

該当のソースコード

dart

11.main.dart 2 3import 'package:flutter/material.dart'; 4import 'package:flutter_state_notifier/flutter_state_notifier.dart'; 5import 'package:future_builder_test/app_page.dart'; 6import 'package:future_builder_test/app_state.dart'; 7import 'package:provider/provider.dart'; 8 9void main() { 10 runApp( 11 MultiProvider( 12 providers: [ 13 StateNotifierProvider<AppController, AppState>( 14 create: (_) => AppController(), 15 ), 16 ], 17 child: MyApp(), 18 ), 19 ); 20} 21 222.app_state.dart 23 24import 'package:freezed_annotation/freezed_annotation.dart'; 25import 'package:future_builder_test/item.dart'; 26import 'package:state_notifier/state_notifier.dart'; 27 28part 'app_state.freezed.dart'; 29 30 31abstract class AppState with _$AppState { 32 const factory AppState({ 33 Items items, 34 (0) int counter, 35 }) = _AppState; 36} 37 38class AppController extends StateNotifier<AppState> { 39 AppController() : super(const AppState()); 40 41 void setItems(Items value) { 42 state = state.copyWith(items: value); 43 } 44 45 Items get items { 46 return state.items; 47 } 48 49 void increment() { 50 state = state.copyWith(counter: state.counter + 1); 51 state.items.add(Item(id: state.counter, counter: state.counter)); 52 } 53} 54 553. app_page.dart 56 57import 'package:flutter/material.dart'; 58import 'package:future_builder_test/app_state.dart'; 59import 'package:future_builder_test/database.dart'; 60import 'package:future_builder_test/item.dart'; 61import 'package:provider/provider.dart'; 62 63class MyApp extends StatelessWidget { 64 65 Widget build(BuildContext context) { 66 return MaterialApp( 67 title: 'Flutter State_Notifier Demo', 68 theme: ThemeData( 69 primarySwatch: Colors.blue, 70 ), 71 home: const HomePage(), 72 ); 73 } 74} 75 76class HomePage extends StatelessWidget { 77 const HomePage({Key key}) : super(key: key); 78 79 80 Widget build(BuildContext context) { 81 final appController = Provider.of<AppController>(context); 82 83 return Scaffold( 84 appBar: AppBar( 85 title: Text('Redraw DataBase'), 86 ), 87 body: FutureBuilder<Items>( 88 future: Items.create( 89 future: AppDatabase.create(), 90 ), 91 builder: (context, snapshot) { 92 if (snapshot.connectionState != ConnectionState.done) { 93 return const Center(child: CircularProgressIndicator()); 94 } 95 if (snapshot.hasData) { 96 context 97 .select((AppController value) => value.setItems(snapshot.data)); 98 return ItemsListPage(); 99 } 100 }, 101 ), 102 floatingActionButton: FloatingActionButton( 103 onPressed: () => {appController.increment()}, 104 tooltip: 'Increment Counter', 105 child: Icon(Icons.add), 106 ), 107 ); 108 } 109} 110 111class ItemsListPage extends StatelessWidget { 112 const ItemsListPage({Key key}) : super(key: key); 113 114 115 Widget build(BuildContext context) { 116 final appController = Provider.of<AppController>(context); 117 118 return FutureBuilder<Object>( 119 future: appController.items?.allItems(), 120 builder: (context, snapshot) { 121 final items = snapshot.data as List<Item> ?? []; 122 return Column( 123 mainAxisAlignment: MainAxisAlignment.center, 124 children: <Widget>[ 125 Expanded( 126 child: ListView.builder( 127 itemCount: items.length, 128 itemBuilder: (context, index) { 129 final item = items[index]; 130 return Center( 131 child: Padding( 132 padding: const EdgeInsets.all(8.0), 133 child: Text(item.counter.toString()), 134 )); 135 }, 136 ), 137 ), 138 ], 139 ); 140 }, 141 ); 142 } 143} 144 1454. app_state.freezed.dart 146ターミナルでflutter packages pub run build_runner buildを実行すると作成されます 147 1485. item.dart 149 150import 'package:future_builder_test/database.dart'; 151 152class Item { 153 Item({this.id, this.counter}); 154 int id; 155 int counter; 156 157 158 Item fromMap(Map map) { 159 return Item( 160 id: map['id'] as int, 161 counter: map['counter'] as int, 162 ); 163 } 164 165 166 Map<String, dynamic> toMap() { 167 return <String, dynamic>{ 168 'id': id, 169 'counter': counter, 170 }; 171 } 172} 173 174class Items { 175 Items(this._database); 176 177 final AppDatabase _database; 178 179 static Future<Items> create({Future<AppDatabase> future}) async { 180 final repository = await future; 181 return Items(repository); 182 } 183 184 Future<void> add(Item item) async { 185 await _database.createItem(item.id, item.toMap()); 186 } 187 188 Future<List<Item>> allItems() async { 189 final objects = await _database.allItems(); 190 return objects.map((map) => Item().fromMap(map)).toList(); 191 } 192} 193 1946. database.dart 195 196import 'package:path/path.dart'; 197import 'package:sqflite/sqflite.dart'; 198import 'package:sqflite/sqlite_api.dart'; 199 200class AppDatabase { 201 AppDatabase._(this.db); 202 203 static const databaseName = 'sample.db'; 204 static const userTable = 'item_table'; 205 static const id = 'id'; 206 static const counter = 'counter'; 207 208 Database db; 209 210 static Future<AppDatabase> create() async => AppDatabase._(await database()); 211 212 static Future<Database> database() async { 213 return openDatabase( 214 join(await getDatabasesPath(), databaseName), 215 onCreate: (db, version) { 216 return db.execute( 217 '''CREATE TABLE $userTable( 218 $id INT PRIMARY KEY, 219 $counter INT 220 )''', 221 ); 222 }, 223 version: 1, 224 ); 225 } 226 227 Future<List<Map<String, dynamic>>> allItems() async { 228 final ret = await db.rawQuery('SELECT * FROM $userTable'); 229 return ret; 230 } 231 232 Future<void> createItem(int key, Map<String, dynamic> object) async { 233 await db.insert(userTable, object, 234 conflictAlgorithm: ConflictAlgorithm.replace); 235 } 236} 237 2387. pubspe.yaml 239 240name: future_builder_test 241description: FutureBuilder Test 242 243publish_to: 'none' # Remove this line if you wish to publish to pub.dev 244 245version: 1.0.0+1 246 247environment: 248 sdk: ">=2.7.0 <3.0.0" 249 250dependencies: 251 flutter: 252 sdk: flutter 253 freezed_annotation: 254 flutter_state_notifier: ^0.4.2 255 provider: ^4.1.3 256 cupertino_icons: ^0.1.3 257 sqflite: ^1.3.1 258 path: ^1.7.0 259 uuid: 2.0.4 260 261dev_dependencies: 262 flutter_test: 263 sdk: flutter 264 build_runner: 265 freezed: 266 pedantic_mono: any 267 268flutter: 269 uses-material-design: true 270

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

Flutter 1.20.0-0.0.pre • channel dev
Dart 2.9.0 (build 2.9.0-14.0.dev 5c1376615e)

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

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

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

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

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

guest

回答2

0

ベストアンサー

ItemsListPageの実装を以下のように、
AppStateを監視するようにしないと状態変更が伝わらないと思います。

dart

1class ItemsListPage extends StatelessWidget { 2 const ItemsListPage({Key key}) : super(key: key); 3 4 5 Widget build(BuildContext context) { 6 final appSate = context.watch<AppState>(); // AppStateの変更を監視 7 8 return FutureBuilder<Object>( 9 future: appSate.items?.allItems(), 10 builder: (context, snapshot) { 11 ~略~

別のエラー

ただこれだけだと以下のエラーが発生しました。
setState() or markNeedsBuild() called during build.

このため以下ページを参考に、とりあえず Database初期化を
initState()へ移動してみましたが、他によい方法があるかもしれません。
https://qiita.com/seiichi3141/items/49f1db76f647335591c6

dart

1class HomePage extends StatelessWidget { 2 const HomePage({Key key}) : super(key: key); 3 4 5 Widget build(BuildContext context) { 6 return Scaffold( 7 appBar: AppBar( 8 title: Text('Redraw DataBase'), 9 ), 10 body: ItemsListPage(), 11 floatingActionButton: FloatingActionButton( 12 onPressed: () => context.read<AppController>().increment(), 13 tooltip: 'Increment Counter', 14 child: Icon(Icons.add), 15 ), 16 ); 17 } 18}

dart

1class AppController extends StateNotifier<AppState> with LocatorMixin { 2 AppController() : super(const AppState()); 3 4 5 void initState() { 6 super.initState(); 7 8 Items.create(future: AppDatabase.create()) 9 .then((items) => this.setItems(items)); 10 } 11 12 void setItems(Items value) { 13 ~略~

投稿2020/07/03 08:15

satokei

総合スコア1217

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

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

copp

2020/07/04 03:12

satokei様、詳しいご返答ありがとうございます。 AppControlを通してAppStateを見ていると監視していることにならないのですね。 すごく勉強になりました。 またinitState()へのDatabase初期化移動なのですが、私の環境下だとDatabaseを移動しなくても(AppControl -> AppStateのみ変更)、エラーにならずに予定した動作をしました。 (Dart,pubspe.yamlのバージョンは以前と同じなのですが、Flutterのバージョンは1.20.0-2.0.preに変わっております。) こちらの理由はわかりませんでしたが、すごく助かりました。 satokei様、本当にありがとうございました。
guest

0

Flutter初学者なのでコードなどはお答えできないですが・・・
StreamBuilderを利用すればできそうな気がします。
https://aimana-it.com/widget-of-the-week-14-streambuilder/

投稿2020/06/26 05:55

no1knows

総合スコア3365

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

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

copp

2020/06/26 11:50

no1kowns様、ご返答頂きありがとうございます。 質問で返答してしまい申し訳ございませんが、 state_notifierの変数はどのようにすればSteamBuilderで使用できるのでしょうか? 調べてみたのですが、分かりませんでした。 大変恐縮ではございますが、御教唆お願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問