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

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

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

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

Dart

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

Q&A

解決済

2回答

707閲覧

TextFieldに値が入っていないときにボタンを無効化したい

j06110611

総合スコア54

Flutter

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

Dart

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

0グッド

0クリップ

投稿2023/09/06 02:44

実現したいこと

TextFieldに値が入っていないときにボタンを無効化したい

前提

調べると全く同じ質問があったので、こちらを参考に102~105行目など見様見真似で書けましたが、TextFieldに値が入っていなくてもボタンが有効なままでした。正直、質問者の102~110行目のソースコードが自分自身理解ができてないので心優しいどなたかわかりやすく教えていただけますでしょうか。

自分の参考前のソースコード

これではTextFieldに値が入ってもボタンが無効のままです。
main.dart抜粋

dart

1class _MyHomePageState extends State<MyHomePage> { 2 SharedPreferencesManager spm = SharedPreferencesManager(); 3 final TextEditingController _doneTextFieldController = TextEditingController(); 4 String _doneText = ''; 5 String _studyTimeText = ''; 6 String _subjectNameText = ''; 7 String _dateText = ''; 8 DateTime now = DateTime.now(); 9 String dropdown1Value = hourNumberList.first; 10 String dropdown2Value = minuteNumberList.first; 11 bool isButtonActive = true; 12 13 14 void dispose() { 15 _doneTextFieldController.dispose(); 16 super.dispose(); 17 } 18 19 void _myDialog() { 20 showDialog( 21 context: context, 22 builder: (context) => AlertDialog( 23 shape: RoundedRectangleBorder( 24 borderRadius: BorderRadius.circular(10), 25 ), 26 title: Text('${now.month}月${now.day}日の取り組み'), 27 content: Column( 28 mainAxisSize: MainAxisSize.min, 29 children: <Widget>[ 30 TextField( 31 //controller: _doneTextFieldController, 32 autofocus: true, 33 decoration: const InputDecoration( 34 labelText: '取り組み', 35 hintText: '今日やったことを入力しよう!' 36 ), 37 onChanged: (value) { 38 setState(() { 39 _doneText = value; 40 }); 41 }, 42 ), 43 Row( 44 children: <Widget> [ 45 const Text('勉強時間:'), 46 Padding( 47 padding: EdgeInsets.only(left: 8), 48 child: StatefulBuilder( 49 builder: (BuildContext context, StateSetter setState) { 50 return DropdownButton<String>( 51 value: dropdown1Value, 52 icon: const Icon(Icons.expand_more), 53 elevation: 8, 54 underline: Container( 55 height: 2, 56 color: Theme.of(context).primaryColor, 57 ), 58 onChanged: (String? value) { 59 setState(() { 60 dropdown1Value = value!; 61 }); 62 }, 63 items: hourNumberList.map<DropdownMenuItem<String>>((String value) { 64 return DropdownMenuItem<String>( 65 value: value, 66 child: Text(value), 67 ); 68 }).toList(), 69 ); 70 }, 71 ), 72 ), 73 const Text('時間'), 74 StatefulBuilder( 75 builder: (BuildContext context, StateSetter setState) { 76 return DropdownButton<String>( 77 value: dropdown2Value, 78 icon: const Icon(Icons.expand_more), 79 elevation: 8, 80 underline: Container( 81 height: 2, 82 color: Theme.of(context).primaryColor, 83 ), 84 onChanged: (String? value) { 85 setState(() { 86 dropdown2Value = value!; 87 }); 88 }, 89 items: minuteNumberList.map<DropdownMenuItem<String>>((String value) { 90 return DropdownMenuItem<String>( 91 value: value, 92 child: Text(value), 93 ); 94 }).toList(), 95 ); 96 }, 97 ), 98 const Text('分'), 99 ] 100 ), 101 TextField( 102 decoration: const InputDecoration( 103 labelText: '教科' 104 ), 105 onChanged: (value) { 106 setState(() { 107 _subjectNameText = value; 108 }); 109 }, 110 ), 111 ], 112 ), 113 actions: [ 114 TextButton( 115 onPressed: () => Navigator.pop(context), 116 child: const Text('やめる'), 117 ), 118 TextButton( 119 onPressed: _doneText.isEmpty ? null :() { 120 Navigator.pop(context); 121 _setStudyTime(); 122 _dateText = '${now.month}月${now.day}日'; 123 _addList(); 124 spm.save(); 125 }, 126 child: const Text('追加する'), 127 ) 128 ], 129 ) 130 ); 131 }

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

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

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

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

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

guest

回答2

0

理想の状態(実現したいこと)と現状の違いから逆向きに考えていけばいいです。
前提から察するに、101行目にあるTextFieldを空文字にしてもボタンが有効なままになってしまう、ということですよね?

まず、Flutterではボタンを押せない状態にする場合は、ボタンのonPressedにnullを渡せばよいです。(それだけではありませんが、省略します)
逆に言えば、現状はonPressedにnullでないものが渡されているから、無効になりません。

無効にしたいボタンは119行目のボタンで、それのonPressedがnullになる条件を見てみると、_doneText.isEmptyの場合しかnullになりませんよね?
では、_doneTextがどこで変化するかというと、30行目のTextFieldのonChangedのみです。
ですから、問題の101行目のTextFieldのonChangedで変更している、_subjectNameTextがいくら変わろうと、ボタンは無効になりません。

おそらく、取り組みと教科を表す変数のどちらかが空文字なら無効にしたいんですよね?なら、無効にする判定条件に両方の変数(_doneTextと_subjectNameText)を加えなければなりません。

無効になる条件は「_doneTextと_subjectNameTextのどちらかが空文字なら」ですから、

onPressed: _doneText.isEmpty || _subjectNameText.isEmpty ? null : (){~}

とすればいいと思います。

投稿2023/09/06 15:03

Shunly

総合スコア152

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

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

0

ベストアンサー

2つの問題点があると思います。

テキストフィールドが2つありその両方にデータが入っているかどうかの判断という部分とテキストフィールドに格納したのにボタンの有効化無効化が変化しないという点。

2つのテキストフィールドの値の利用方法はShunlyさんの回答の通り。

これではTextFieldに値が入ってもボタンが無効のままです。

こちらの方はAlertDialogをさらにStatefulBuildeでラッピングしてみてください。

該当部分だけ書くと、以下の様な感じかな。

dart

1 showDialog( 2 context: context, 3 builder: (context) => StatefulBuilder( 4 builder: (context, setState) { 5 return AlertDialog( 6 shape: RoundedRectangleBorder(

変更前のソースだと、TextFieldで行うsetState_MyHomePageStateのウィジェット更新に使われ、AlertDialogウィジェットは更新対象外となります。

AlertDialogが対象外となるのは、showDialogで表示されるページに紐づけされるものとなるため、_MyHomePageStateとは完全に独立したウィジェットになるためです。

ウィジェットの更新対象がなんになるのか、またどこまで対象となるのかは、どういった更新をされるのか、理屈を知ってないと分かりづらいものがあります。今回のもそういったものの一つになるかもしれません。

投稿2023/09/06 23:40

ta.fu

総合スコア1740

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

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

j06110611

2023/09/07 03:09

ご丁寧な解説のおかげさまで理解して解決できました! ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問