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

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

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

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

Dart

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

Q&A

解決済

1回答

584閲覧

【Flutter】RadioListTileの値をElevatedbuttonタップ後に更新することはできますか?

my0930

総合スコア19

Flutter

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

Dart

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

0グッド

0クリップ

投稿2022/10/01 06:43

編集2022/10/01 07:48

前提

RadioListTileで選択項目を選択し、その値をElevatedbuttonで
登録することができています。
登録成功後、snackBarを表示させることにしたのですが、
onpressedのlabel:【OK】ボタンはNavigator.of(context).pop();を設定しており、
連続で登録されると、snackBarも連続で出てしまいます。
画面が戻った先でも表示されてしまうので、
【OK】ボタンを押したらRadioListTileの選択項目がリセットできれば、
一回一回表示されないと考えました。

実現したいこと

RadioListTileの値が、Elevatedbutton押下後、nullに更新される。

該当のソースコード

main

1class InstructionPage extends StatefulWidget { 2 InstructionPage({Key? key, required this.users}) : super(key: key); 3 4 DocumentSnapshot users; 5 @override 6 State<InstructionPage> createState() => _InstructionPageState(); 7} 8 9class _InstructionPageState extends State<InstructionPage> { 10 String currentName = ""; 11 @override 12 Widget build(BuildContext context) { 13 return ChangeNotifierProvider<WorkListModel>( 14 create: (_) => WorkListModel()..fetchWorkList(), 15 child: Scaffold( 16 appBar: AppBar( 17 title: Text("指示選択"), 18 ), 19 body: Column( 20 mainAxisAlignment: MainAxisAlignment.center, 21 children: [ 22 Card( 23 margin: const EdgeInsets.all(30), 24 elevation: 8, 25 shadowColor: Colors.black, 26 shape: RoundedRectangleBorder( 27 borderRadius: BorderRadius.circular(10), 28 ), 29 child: Column( 30 children: [ 31 ListTile( 32 leading: CircleAvatar( 33 backgroundImage: NetworkImage(widget.users["imagePath"]), 34 ), 35 title: Text(widget.users["name"]), 36 subtitle: Text(widget.users["status"].toString()), 37 ), 38 ], 39 ), 40 ), 41 ChangeNotifierProvider<WorkListModel>( 42 create: (_) => WorkListModel()..fetchWorkList(), 43 child: SizedBox( 44 height: 300, 45 child: Center(child: 46 Consumer<WorkListModel>(builder: (context, model, child) { 47 final works = model.works; 48 49 if (works == null) { 50 return const CircularProgressIndicator(); 51 } 52 53 final List<Widget> widgets = works 54 .map((workname) => RadioListTile<dynamic>( 55 groupValue: currentName, 56 title: Text(workname.name), 57 value: workname.name, 58 onChanged: (value) { 59 setState(() { 60 debugPrint('workname = $value'); 61 currentName = value!; 62 debugPrint('$currentName'); 63 }); 64 // model.setListTile(value); 65 }, 66 )) 67 .toList(); 68 return ListView(children: widgets); 69 })), 70 ), 71 ), 72 ChangeNotifierProvider<WorkListModel>( 73 create: (_) => WorkListModel(), 74 child: Container( 75 child: Consumer<WorkListModel>( 76 builder: ((context, model, child) { 77 return ElevatedButton( 78 child: const Text("決定"), 79 onPressed: () async { 80 if (currentName != "") { 81 try { 82 await model.addWork(currentName, 83 widget.users["name"], widget.users["uid"]); 84 await model.addHistory(currentName, 85 widget.users["name"], widget.users["uid"]); 86 model.resetWork(currentName); 87 print("タップ後$currentName"); 88 ScaffoldMessenger.of(context).showSnackBar(SnackBar( 89 duration: const Duration(milliseconds: 500), 90 behavior: SnackBarBehavior.floating, 91 content: Text("指示が飛ばされました!"), 92 action: SnackBarAction( 93 label: "OK", 94 onPressed: () async { 95 print('SnackBarActionをクリックしました'); 96 // Navigator.of(context).pop(); 97 ScaffoldMessenger.of(context) 98 .hideCurrentSnackBar(); 99 }, 100 ))); 101 } catch (e) { 102 print("$e==保存エラーです。"); 103 const CircularProgressIndicator(); 104 } 105 } else { 106 showDialog( 107 context: context, 108 builder: (context) { 109 return AlertDialog( 110 title: const Text("エラー"), 111 content: const Text("指示する項目を選択してください"), 112 actions: [ 113 TextButton( 114 onPressed: () { 115 Navigator.of(context).pop(); 116 }, 117 child: const Text("OK")) 118 ], 119 ); 120 }, 121 ); 122 } 123 }, 124 ); 125 }), 126 ), 127 ), 128 ) 129 ], 130 ), 131 ), 132 ); 133 } 134} 135 136

model

1import 'package:cloud_firestore/cloud_firestore.dart'; 2import 'package:flutter/cupertino.dart'; 3import 'package:main/model/work.dart'; 4 5class WorkListModel extends ChangeNotifier { 6 final _workCollection = FirebaseFirestore.instance.collection("work"); 7 8 List<Work>? works; 9 10 String? workerName; 11 String? workName; 12 bool? complite; 13 int? manHour; 14 int? phase; 15 Timestamp? startTime; 16 17 String? uid; 18 String? documentId; 19 20 Timestamp? endTime; 21 22 void resetWork(String currentName) { 23 currentName = ""; 24 notifyListeners(); 25 } 26 27 void setListTile(String value) { 28 String value = ""; 29 notifyListeners(); 30 } 31 32 void fetchWorkList() async { 33 final QuerySnapshot snapshot = await _workCollection.get(); 34 35 final List<Work> works = snapshot.docs.map((DocumentSnapshot document) { 36 Map<String, dynamic> data = document.data()! as Map<String, dynamic>; 37 final String name = data["name"]; 38 final int manHour = data["manHour"]; 39 return Work(name: name, manHour: manHour); 40 }).toList(); 41 42 this.works = works; 43 notifyListeners(); 44 } 45 46 Future addWork( 47 String currentName, 48 String workerName, 49 String uid, 50 ) async { 51 switch (currentName) { 52 case "掃除": 53 manHour = int.parse("5"); 54 break; 55 case "ピッキング": 56 manHour = int.parse("6"); 57 break; 58 case "プログラム": 59 manHour = int.parse("5"); 60 break; 61 case "休憩": 62 manHour = int.parse("1"); 63 break; 64 default: 65 } 66 67 final addNowWork = FirebaseFirestore.instance.collection("nowWork").doc(); 68 69 addNowWork.set({ 70 "complite": false, 71 "manHour": manHour, 72 "phase": 0, 73 "workerName": workerName, 74 "workName": currentName, 75 "startTime": Timestamp.now(), 76 "uid": uid, 77 "documentId": addNowWork.id, 78 }); 79 } 80 81 Future addHistory( 82 String currentName, 83 String workerName, 84 String uid, 85 ) async { 86 final addworkHistory = 87 FirebaseFirestore.instance.collection("work_history").doc(); 88 89 addworkHistory.set({ 90 "isComplite": false, 91 "workerName": workerName, 92 "workName": currentName, 93 "startTime": Timestamp.now(), 94 "uid": uid, 95 "documentId": addworkHistory.id, 96 "endTime": endTime, 97 }); 98 } 99} 100

試したこと

setResetメソッドを作ってみましたが
反映されず。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

データベースの更新?とGUIの更新はそれぞれ非同期で行われるので、「決定」ボタンを押した後「決定」ボタンを押せないようにonPressedをnullにした状態に持っていくのは難しいかも。

仕様(前提条件)を変更し、「決定」ボタンを押した後、その処理が終わるまで「決定」ボタンを押しても「決定」に関する処理を行わないようする、という感じにすればいいのでは。

具体的には、「決定」ボタンが押されたら処理中のbool値をtrueにし、それがfalseにならない限り本来の「決定」処理を行わないようにする、という感じに処理を変更する。

その処理の一環としてonPressedをnullにする処理を入れるというのはありかもしれない。

投稿2022/10/01 13:14

ta.fu

総合スコア1667

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

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

my0930

2022/10/02 23:39

なるほど!決定ボタンのあとにさらにスイッチを作る感じでしょうか? ありがとうございます。試作してみたいと思います。
my0930

2022/10/03 04:27

初期値falseを置いて、 決定ボタン後trueにし、snackbarのokボタンがtrueのときのみ navigaitor.popしてfalseに変換したら 連続で戻りすぎないでクラッシュせずに済みました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問