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

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

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

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

Q&A

1回答

1500閲覧

【flutter】複数画面にわたって収集する情報を一時保管したい

OSARU_2020

総合スコア15

Flutter

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

0グッド

0クリップ

投稿2021/09/07 16:30

編集2021/09/07 16:32

新規ユーザーの登録ページを作成しているのですが、
ページAではユーザー名、性別、誕生日などをTextFiledなどで収集し、
ページBでは他の情報を収集、
最後にページCでA〜Cにて収集した情報をまとめて一気にFireStoreに保存したいのですが、
どういう方法がありますか?

・ページ移動の際に情報を常に引き渡しする
などが考えられると思うのですが、ページBからAに戻る際(Navigator.pop())に渡し方が分からなかったりで、
どういう方法がベストか教えていただきたいです。

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

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

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

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

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

guest

回答1

0

Providerを使って書いてみました。
イメージとしては、ChangeNotifierを継承したInfoStore君にずっと情報(状態)を持っておいてもらって、
必要なときにそれを引き出すと言った感じですね。
もっと良いやり方・書き方があるかもしれませんが、この方法で困った経験はあまりないです。

main.dart

flutter

1import 'package:flutter/material.dart'; 2import 'package:provider/provider.dart'; 3 4void main() { 5 runApp(ChangeNotifierProvider( 6 create: (_) => InfoStore(), 7 child: const MyApp(), 8 )); 9} 10 11class MyApp extends StatelessWidget { 12 const MyApp({Key? key}) : super(key: key); 13 @override 14 Widget build(BuildContext context) { 15 return MaterialApp( 16 title: 'FlutterLabo', 17 theme: ThemeData( 18 scaffoldBackgroundColor: Colors.white, 19 primarySwatch: Colors.blue, 20 ), 21 debugShowCheckedModeBanner: false, 22 home: const FirstPage( 23 title: 'FirstPage', 24 ), 25 ); 26 } 27} 28 29class FirstPage extends StatelessWidget { 30 const FirstPage({Key? key, required this.title}) : super(key: key); 31 final String title; 32 33 @override 34 Widget build(BuildContext context) { 35 return Scaffold( 36 appBar: AppBar( 37 title: Text(title), 38 ), 39 body: Consumer<InfoStore>(builder: (_, infoStore, __) { 40 return Column( 41 mainAxisAlignment: MainAxisAlignment.center, 42 children: <Widget>[ 43 Column( 44 children: [ 45 const Text('メアドを入力'), 46 TextFormField( 47 onChanged: (String newValue) => 48 infoStore.changeMail(newValue)), 49 Text( 50 infoStore.mailError, 51 style: const TextStyle(color: Colors.red), 52 ) 53 ], 54 ), 55 ], 56 ); 57 }), 58 floatingActionButton: FloatingActionButton( 59 onPressed: () { 60 Navigator.push<void>( 61 context, 62 MaterialPageRoute( 63 builder: (context) => const SecondPage(), 64 )); 65 }, 66 child: const Icon(Icons.arrow_forward), 67 ), 68 ); 69 } 70} 71 72class SecondPage extends StatelessWidget { 73 const SecondPage({Key? key}) : super(key: key); 74 75 @override 76 Widget build(BuildContext context) { 77 return Scaffold( 78 appBar: AppBar( 79 title: const Text('SecondPage'), 80 ), 81 body: Column( 82 mainAxisAlignment: MainAxisAlignment.center, 83 children: <Widget>[ 84 const Text('住所を入力'), 85 TextFormField( 86 onChanged: (String newValue) => 87 context.read<InfoStore>().changeAddress(newValue)), 88 ], 89 ), 90 floatingActionButton: FloatingActionButton( 91 onPressed: () { 92 Navigator.push<void>( 93 context, 94 MaterialPageRoute( 95 builder: (context) => const ThirdPage(), 96 )); 97 }, 98 child: const Icon(Icons.arrow_forward), 99 ), 100 ); 101 } 102} 103 104class ThirdPage extends StatelessWidget { 105 const ThirdPage({Key? key}) : super(key: key); 106 107 @override 108 Widget build(BuildContext context) { 109 return Scaffold( 110 appBar: AppBar( 111 title: const Text('ThirdPage'), 112 ), 113 body: Column( 114 mainAxisAlignment: MainAxisAlignment.center, 115 children: [ 116 const Text('今までの入力データ'), 117 Text(context.read<InfoStore>().mail), 118 Text(context.read<InfoStore>().address), 119 const Text('性別を入力'), 120 TextFormField( 121 onChanged: (String newValue) => 122 context.read<InfoStore>().changeGender(newValue)), 123 ElevatedButton( 124 onPressed: () { 125 print('メアド'); 126 print(context.read<InfoStore>().mail); 127 print('住所'); 128 print(context.read<InfoStore>().address); 129 print('性別'); 130 print(context.read<InfoStore>().gender); 131 }, 132 child: const Text('ファイアストアに情報を送る')) 133 ], 134 ), 135 ); 136 } 137} 138 139class InfoStore with ChangeNotifier { 140 String mail = ''; 141 String address = ''; 142 String gender = ''; 143 //validationしたい時に使う 144 String mailError = ''; 145 146 //TextFormFieldが変更された時に行う処理 147 void changeMail(String newValue) { 148 mail = newValue; 149 mailError = validateMail(newValue); 150 notifyListeners(); 151 } 152 153 void changeAddress(String newValue) { 154 address = newValue; 155 notifyListeners(); 156 } 157 158 void changeGender(String newValue) { 159 gender = newValue; 160 notifyListeners(); 161 } 162 163 String validateMail(String newValue) { 164 if (!mail.contains('@')) { 165 return '@が含まれていません'; 166 } else { 167 return ''; 168 } 169 } 170} 171

pubspec.yaml

dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.2 provider: ^6.0.0

投稿2021/09/08 02:21

flutter_labo

総合スコア110

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

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

OSARU_2020

2021/09/08 16:17

回答いただきありがとうございました! 参考にして作ってみたのですが上手く行かずでした、、 FirstPageはConsumerで囲んでいるのですが、それ以降のページは故意的に囲んでいないのでしょうか? 全ページにChangeNotifierProviderとConsumerで囲んでみたのですが、それでも最後のページの情報しかFireStoreに登録できなかったです。。
flutter_labo

2021/09/09 03:28

Consumerで囲んでいないのは意図的で、その部分での画面の再構築が不必要だと判断したからです。 それと、FirstPageのみでConsumerを使った理由は、infoStore.mailErrorを再構築して表示させたかったからです。 あと、ChangeNotifierProviderを全ページで使うのはダメです。私のコードで言うと、InfoStoreのインスタンスが複数個できてしまうことになるからです。(createではなくvalueにすればいけそうですが) というわけでまずは、ChangeNotifierProviderをmain関数内で一度だけ使用するようにしてみて下さい(私のコードが参考になるかと思います)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問