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

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

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

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

Dart

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

Q&A

解決済

2回答

3903閲覧

flutter 画面遷移先で渡された値を初期表示させたい

satoshiiiin

総合スコア2

Flutter

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

Dart

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

0グッド

0クリップ

投稿2021/09/11 07:11

編集2021/09/11 07:25

実現したいこと

flutterで画面遷移の実装をしていて、
前の画面の値を遷移先の画面上で初期表示させたい。

###前提
前の画面の値はWorkDataクラスのインスタンスとして更新画面に渡している。
問題のTextFormFieldではshowTimePickerを使用して、動的に表示を変更させたいので、
controllerプロパティを使用したい。

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

TextFormFieldに初期値として、initialValueに値を設定しようとしたが、下記エラーが発生。

'package:flutter/src/material/text_form_field.dart': Failed assertion: line 198 pos 15: 'initialValue == null || controller == null': is not true.

どうも、TextFormFieldはinitialValueとcontrollerプロパティは共存出来ないっぽい。
参照:Flutter - 'initialValue == null || controller == null': is not true. error

試したこと

上記参照の通り、TextEditingControllerの引数にWorkDataクラスのインスタンスを渡そうとしたが、渡されたインスタンスへアクセスが出来ず。

該当のソースコード

dart

1import 'package:flutter/material.dart'; 2import 'package:flutter/services.dart'; 3import 'package:shukan_app/models/work_data.dart'; 4 5class WorkForm extends StatefulWidget { 6 final String buttonText; 7 final WorkData? workData; 8 9 const WorkForm({ 10 Key? key, 11 required this.buttonText, 12 this.workData, 13 }) : super(key: key); 14 15 16 _WorkFormState createState() => _WorkFormState(); 17} 18 19class _WorkFormState extends State<WorkForm> { 20 String _text = ''; 21 String _timer = ''; 22 TimeOfDay _timeOfDay = TimeOfDay(hour: 0, minute: 0); 23 24 final _startTimeInputController = new TextEditingController(widget.workData!.startTime);//error: The instance member 'widget' can't be accessed in an initializer. 25 //Try replacing the reference to the instance member with a different expression 26 final _formKey = GlobalKey<FormState>(); 27 28 29 Widget build(BuildContext context) { 30 return Form( 31 key: _formKey, 32 child: Column( 33 mainAxisAlignment: MainAxisAlignment.center, 34 children: [ 35 TextFormField( 36 initialValue: widget.workData != null ? widget.workData!.title : '', 37 onChanged: (String value) { 38 setState( 39 () { 40 _text = value; 41 }, 42 ); 43 }, 44 validator: (value) { 45 if (value == null || value.isEmpty) { 46 return 'タイトルを記入してください'; 47 } 48 return null; 49 }, 50 decoration: InputDecoration( 51 border: OutlineInputBorder(), 52 labelText: 'タイトル', 53 counterText: ''), 54 maxLength: 20, 55 ), 56 SizedBox(height: 8), 57 TextFormField(// ここのwidgetの初期値として、workData.startTimeを渡したい。 58 controller: _startTimeInputController, 59 onTap: () async { 60 final TimeOfDay? timeOfDay = await showTimePicker(//時間を入力 61 context: context, initialTime: _timeOfDay); 62 if (timeOfDay != null) 63 setState(() { 64 _timeOfDay = timeOfDay; 65 _startTimeInputController.text = //入力した時間を動的に表示させたい為、_startTimeInputControllerを使用 66 '${timeOfDay.format(context)}'; 67 }); 68 }, 69 validator: (value) { 70 if (value == null || value.isEmpty) { 71 return '開始時間を記入してください'; 72 } 73 return null; 74 }, 75 decoration: InputDecoration( 76 border: OutlineInputBorder(), labelText: '開始時間'), 77 ), 78 SizedBox(height: 8), 79 TextFormField( 80 initialValue: widget.workData != null ? widget.workData!.timer : '', 81 onChanged: (String value) { 82 setState( 83 () { 84 _timer = value; 85 }, 86 ); 87 }, 88 validator: (value) { 89 if (value == null || value.isEmpty) { 90 return 'タイマー(分)を記入してください'; 91 } 92 return null; 93 }, 94 decoration: InputDecoration( 95 border: OutlineInputBorder(), 96 labelText: 'タイマー(分)', 97 counterText: ''), 98 keyboardType: TextInputType.number, 99 inputFormatters: [FilteringTextInputFormatter.digitsOnly], 100 maxLength: 3, 101 ), 102 SizedBox(height: 8), 103 Container( 104 width: double.infinity, 105 child: ElevatedButton( 106 onPressed: () { 107 if (_formKey.currentState!.validate()) { 108 Navigator.of(context) 109 .pop(WorkData(_text, _timeOfDay, _timer)); 110 } 111 }, 112 child: Text(widget.buttonText), 113 ), 114 ), 115 ], 116 ), 117 ); 118 } 119} 120

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

flutter: 2.2.3

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

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

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

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

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

guest

回答2

0

自己解決

endivさんの回答を参考にさせて頂き、解決しました。
ありがとうございます。

解決方法:
lateを使用して宣言するとthisを参照できるみたいなので、宣言時にTextEditingControllerの引数に初期値を設定しました。
参照:【Flutter】 Dart 2.12で追加されたlateについて

dart

1 late TextEditingController _startTimeInputController = 2 new TextEditingController(widget.workData!.startTime.format(context));

また、initState内で宣言する方法ですと、initState()が完了しないうちに処理を実行したとして、下記エラーが発生しましたが、解決策がいくつかありましたので、参考に書いときます。
エラー:

dependOnInheritedWidgetOfExactType<_LocalizationsScope>() or dependOnInheritedElement() was called before _WorkFormState.initState() completed.

解決方法:
①didChangeDependenciesを使用して、initState完了後に処理を実行する。

dart

1 2 void didChangeDependencies() { 3 super.didChangeDependencies(); 4 _startTimeInputController = new TextEditingController(widget.workData!.startTime.format(context)); 5 }

②initState内でFutureを使用して無理やりinitStateが完了するのを待つ

dart

1 2 void initState() { 3 super.initState(); 4 Future.delayed(Duration(seconds: 1), () { 5 _startTimeInputController = new TextEditingController(widget.workData!.startTime.format(context)); 6 }); 7 }

参照元でも書いていましたが、①のdidChangeDependenciesを使用したほうが良さげな気がします。
参照:Unhandled Exception: inheritFromWidgetOfExactType(_LocalizationsScope) or inheritFromElement() was called before _ScreenState.initState() completed

投稿2021/09/12 05:19

編集2021/09/12 05:23
satoshiiiin

総合スコア2

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

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

0

dart

1late TextEditingController _startTimeInputController; 2 3void initState() { 4 _startTimeInputController = newTextEditingController(widget.workData!.startTime); 5 super.initState(); 6} 7

間違ってたら申し訳ない

投稿2021/09/11 15:53

endiv

総合スコア161

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

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

satoshiiiin

2021/09/12 05:00

回答ありがとうございます。 上記試した結果、下記エラーが発生しました。 どうやら、initState()が完了する前に処理を実行するのは良くないみたいです。 dependOnInheritedWidgetOfExactType<_LocalizationsScope>() or dependOnInheritedElement() was called before _WorkFormState.initState() completed. 参照: https://stackoverflow.com/questions/56395081/unhandled-exception-inheritfromwidgetofexacttype-localizationsscope-or-inheri
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問