[Flutter]変数の値の変化でボタンの色を変化させたい。
登録フォーム画面を作成しているのですが、各フォームの内容を埋めると送信ボタンの色が変わって次の画面へ遷移できる様にしたいです。
発生している問題
[変数の値変更⇨ボタンのbool値パラメータを変更する]
これをするためのsetStateのトリガーをどこに置くのかわからない。
考えていること
onChanged:(){}のようなものでScreenのクラスの描画を更新できないかと思いましたが、それもだめそう?
該当のソースコード
※ボタン・テキストフォームなどのパーツを、画面のファイルとは別ファイルで保存してます。
※実際作成してるものを簡略化しています。実際はもっとフォーム項目が多いです。
画面
Screen
1class FormPage extends StatefulWidget { 2 @override 3 _FormPageState createState() => _FormPageState(); 4} 5 6class _FormPageState extends State<FormPage> { 7 final _mailController = TextEditingController(); 8 String _selectedGender = null; 9 bool _buttonAvailable = false; 10 11 @override 12 Widget build(BuildContext context) { 13 return Scaffold( 14 body:Container( 15 margin:EdgeInsets.all(30), 16 child:Column( 17 children:[ 18 AppTextFieldWidget( 19 title:"メールアドレス", 20 controller: _mailController, 21 ), 22 SelectBox( 23 onValueSelected:(value){ 24 setState((){ 25 _selectedGender = value; 26 }); 27 } 28 ), 29 AppButtonWidget( 30 title:"確認画面へ", 31 buttonAvailable:_buttonAvailable, 32 onPressed:(){ 33 _validationAll(); 34 } 35 ), 36 ] 37 ) 38 ) 39 ); 40 } 41 void _validationAll(){ 42 if(_mailController.text.isNotEmpty && _selectedGender != null){ 43 _continueNextPage(); 44 setState((){ 45 _buttonAvailable = true; 46 }); 47 _continueNextPage(); 48 } 49 } 50 void _continueNextPage(){ 51 Navigator.push( 52 context, 53 MaterialPageRoute(builder:(context){ 54 return SecondPage(); 55 }) 56 ); 57 } 58} 59 60class SecondPage extends StatelessWidget { 61 @override 62 Widget build(BuildContext context) { 63 return Center(child:Text("遷移後画面")); 64 } 65}
ボタン
Button
1class AppButtonWidget extends StatefulWidget { 2 const AppButtonWidget({ 3 @required this.title, 4 @required this.onPressed, 5 this.buttonAvailable = true, 6 }); 7 final String title; 8 final GestureTapCallback onPressed; 9 final bool buttonAvailable; 10 @override 11 _AppButtonWidgetState createState() => _AppButtonWidgetState(); 12} 13 14class _AppButtonWidgetState extends State<AppButtonWidget> { 15 @override 16 Widget build(BuildContext context) { 17 return Container( 18 padding:EdgeInsets.all(30), 19 child:FlatButton( 20 color:(widget.buttonAvailable) ? Colors.blue : Colors.grey, 21 onPressed:(widget.buttonAvailable) ? widget.onPressed : null, 22 child:Text( 23 widget.title, 24 ) 25 ) 26 ); 27 } 28}
テキストフィールド
Text
1class AppTextFieldWidget extends StatelessWidget { 2 3 const AppTextFieldWidget({ 4 this.title, 5 this.hintText, 6 this.maxLength = 100, 7 this.controller, 8 }); 9 10 final String title; 11 final String hintText; 12 final int maxLength; 13 final TextEditingController controller; 14 15 @override 16 Widget build(BuildContext context) { 17 return Container( 18 child: TextField( 19 enabled: true, 20 controller:controller, 21 decoration: InputDecoration( 22 labelText: title, 23 hintText: hintText, 24 ) 25 ) 26 ); 27 } 28}
ドロップダウンのセレクトボックス
Select
1class SelectBox extends StatefulWidget{ 2 final Function(String) onValueSelected; 3 4 const SelectBox({ 5 this.onValueSelected, 6 }); 7 @override 8 SelectBoxState createState() => SelectBoxState(); 9} 10 11class SelectBoxState extends State<SelectBox>{ 12 String dropdownValue; 13 List<String> genderQuestionContents = ["男性","女性","その他"]; 14 15 16 @override 17 Widget build(BuildContext context){ 18 return Container( 19 child:DropdownButton<String>( 20 isExpanded: true, 21 value: dropdownValue, 22 itemHeight: 60, 23 icon: Icon(Icons.arrow_downward), 24 style:TextStyle(color: Colors.black54), 25 underline: Container( 26 color: Colors.black54, 27 ), 28 onChanged: (String newValue){ 29 setState((){ 30 dropdownValue = newValue; 31 widget.onValueSelected(dropdownValue); 32 }); 33 }, 34 items:genderQuestionContents 35 .map<DropdownMenuItem<String>>((String value){ 36 return DropdownMenuItem<String>( 37 value: value, 38 child: Text(value), 39 ); 40 }).toList(), 41 ) 42 ); 43 } 44}
回答1件
あなたの回答
tips
プレビュー