ListViewの中に下の画像のようなWidgetがあります。
チェックボタンがチェックされると文字の真ん中に線が引かれるようにしたいです。
ListTile
のtrailingにChechbox
のカスタムWidgetを指定し、引数にチェックボタンの状態を表すbool値と、そのbool値を反映する関数を渡しています。
import 'package:flutter/material.dart'; class TaskTile extends StatefulWidget { const TaskTile({ Key? key, }) : super(key: key); @override State<TaskTile> createState() => _TaskTileState(); } class _TaskTileState extends State<TaskTile> { bool isChecked = false; // チェックボタンのBool値を反映する void checkboxCallback(bool checkboxState) { setState(() { isChecked = checkboxState; }); } @override Widget build(BuildContext context) { return ListTile( title: Text( 'This is a task', style: TextStyle( decoration: isChecked ? TextDecoration.lineThrough : null), ), // カスタムチェックボックス trailing: TaskCheckbox( checkboxState: isChecked, toggleCheckboxState: checkboxCallback, // 関数そのものを渡す ), ); } } class TaskCheckbox extends StatelessWidget { TaskCheckbox({this.checkboxState, this.toggleCheckboxState}); final bool? checkboxState; final Function? toggleCheckboxState; @override Widget build(BuildContext context) { return Checkbox( value: checkboxState!, // チェック時に関数実行 onChanged: toggleCheckboxState!(checkboxState!), ); } }
この状態で動かすと膨大なエラー分が発生しました。
以下は一番先頭にあったエラーです。
======== Exception caught by widgets library ======================================================= The following assertion was thrown building TaskCheckbox(dirty): setState() or markNeedsBuild() called during build. This TaskTile widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase. The widget on which setState() or markNeedsBuild() was called was: TaskTile state: _TaskTileState#472c8 The widget which was currently being built when the offending call was made was: TaskCheckbox dirty The relevant error-causing widget was: TaskCheckbox file:///Users/kudokoki/AndroidStudioProjects/Flutter/appbrewery/today_flutter/lib/widgets/task_tile.dart:30:17 When the exception was thrown, this was the stack: #0 Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:4298:11) #1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:4313:6) #2 State.setState (package:flutter/src/widgets/framework.dart:1108:15) #3 _TaskTileState.checkboxCallback (package:today_flutter/widgets/task_tile.dart:16:5) #4 TaskCheckbox.build (package:today_flutter/widgets/task_tile.dart:49:38) #5 StatelessElement.build (package:flutter/src/widgets/framework.dart:4732:28) #6 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4658:15) #7 Element.rebuild (package:flutter/src/widgets/framework.dart:4348:5) #8 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4636:5) #9 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4631:5) ... Normal element mounting (27 frames) #36 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3666:14) #37 Element.updateChild (package:flutter/src/widgets/framework.dart:3418:18) #38 _ListTileElement._mountChild (package:flutter/src/material/list_tile.dart:1322:31) #39 _ListTileElement.mount (package:flutter/src/material/list_tile.dart:1337:5) ... Normal element mounting (164 frames) (elided 11 frames from class _RawReceivePortImpl, class _Timer, dart:async, and dart:async-patch) ==================================================================================================== ...
setState()
が悪さしてると思い、文字列を出力するだけの処理に変えたところ、なぜかチェックボタンを押していないのに2回実行されてしまいます。
void checkboxCallback(bool checkboxState) { - setState(() { - isChecked = checkboxState; - }); + print('call backed'); }
console
1Performing hot restart... 2Syncing files to device iPhone XR... 3Restarted application in 879ms. 4flutter: call backed 5flutter: call backed
膨大なエラー以前に、なぜ押してもいないチェックボタンの処理が実行(しかも2回)されるのでしょうか?
教材に沿って進めているのですが、そのような解説もなく、エラー文で検索しようにも膨大すぎる文量なので困っています。
ご助力お願いします。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。