we_*_*mor 7 flutter flutter-web flutter-getx
我正在使用 flutter 和GetX,所以我Obx在我的代码中实现。
我有3个文件:
questionnaire.dart
questionnnaire_controller.dart
popup.dart
在里面popup.dart我有弹出窗口的布局。
在里面questionnaire.dart我有显示弹出窗口内容的代码,该弹出窗口显示要回答的调查问卷。
在里面questionnaire_controller.dart我有一些使用的变量和函数,比如getQuestionnaires()异步获取调查问卷数据的函数,或者 list ,或者保存已选择的调查问卷实例的questionnaires变量。selectedQuestionnaire
如果已选择调查问卷,则必须在弹出对话框的顶部popup.dart显示调查问卷的标题。部分代码如下:
static Future<void> showQuestionnaireInput({String title, Widget child, Widget icon}) async {
bool mobileSize = Get.size.width <= ResponsiveSizingConfig.instance.breakpoints.desktop;
if (mobileSize) {
await Get.to(InputScreenWidget(child, title));
} else {
await showDialog(
context: Get.context,
builder: (context) {
return AlertDialog(
titlePadding: EdgeInsets.all(8),
contentPadding: EdgeInsets.all(8),
title: Container(
decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey.shade200, width: 2))),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: EdgeInsets.only(left: 4),
child: Row(
children: [
if (icon != null) icon,
if (icon != null) SizedBox(width: 4),
Text(title),
Obx(() {
if(questionnaireController.selectedQuestionnaireTitle.value != '')
return Text(questionnaireController.selectedQuestionnaireTitle.value);
else
return Container();
}),
],
),
),
CloseButton(
onPressed: () {
Get.back();
},
)
],
),
),
content: child,
);
});
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,在 obx 中,我获取了 selectedQuestionnaireTitle 的值,它是 中存在的一个变量questionnnaire_controller.dart。
在我的内部questionnaire.dart有一个future builder带有我的调查问卷数据的表单,以便用户通过下拉菜单选择其中一个,并通过单击“下一步”回答相应的问题。对我们的案例有用的部分代码如下:
child: Obx(() {
if (questionnaireController.questionnaireState.value == QuestionnaireController.QUESTIONNAIRE_CHOOSE) {
return Container(
width: screenWide ? Get.size.width * 0.5 : Get.size.width * 1,
child: Center(
child: FutureBuilder(
future: questionnaireController.getQuestionnaires(),
builder: (context, snapshot) {
questionnaireController.dialIsBuilt.value = true;
print(questionnaireController.dialIsBuilt.value);
switch (snapshot.connectionState) {
case ConnectionState.waiting:
questionnaireController.dialIsBuilt.value = false;
print(questionnaireController.dialIsBuilt.value);
return CircularProgressIndicator();
default:
if (snapshot.hasData) {
print(questionnaireController.dialIsBuilt.value);
return Column(
children: [
Text(
'choose_questionnaire'.tr,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: TextSize.TEXT_LARGE,
fontWeight: FontWeight.w600,
color: EnvironmentVariables.mainColor,
),
),
SizedBox(
height: 8,
),
Dropdown(
questionnaires: questionnaireController.questionnaires,
selectedQuestionnaire: questionnaireController.selectedQuestionnaire,
),
Obx(
() {
if (questionnaireController.buttonDisplay.value == true) {
return Container(
margin: EdgeInsets.all(16),
child: defaultButton(
text: 'next_question'.tr,
onPressed: () {
questionnaireController.answerQuestionnaire();
},
),
);
} else {
return Container();
}
},
),
],
);
} else
return Column(
children: [
Text(
'choose_questionnaire'.tr,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: TextSize.TEXT_LARGE,
fontWeight: FontWeight.w600,
color: EnvironmentVariables.mainColor,
),
),
// Text("no_data".tr),
SizedBox(
height: 32,
)
],
);
}
}),
),
);
}
Run Code Online (Sandbox Code Playgroud)
您可以在上面的代码中看到一个名为 的小部件Dropdown。这是我创建的一个有状态的小部件。这个小部件,也存在于questionnaire.dart. 其代码Dropdown如下。
class Dropdown extends StatefulWidget {
final List questionnaires;
final Questionnaire selectedQuestionnaire;
Dropdown({
this.questionnaires,
this.selectedQuestionnaire,
});
@override
_DropdownState createState() => _DropdownState(
questionnaires: questionnaires,
// dropdownValue: selectedQuestionnaire.title,
);
}
class _DropdownState extends State<Dropdown> {
List questionnaires;
String dropdownValue = questionnaireController.selectedQuestionnaire.title;
_DropdownState({
this.questionnaires,
// this.dropdownValue,
});
@override
Widget build(BuildContext context) {
questionnaireController.setSelectedQuestionnaire(questionnaireController.selectedQuestionnaire);
return DropdownButton(
isExpanded: true,
value: dropdownValue,
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: TextStyle(color: EnvironmentVariables.mainColor, fontSize: TextSize.TEXT_SMALL),
underline: Container(
height: 1.6,
color: EnvironmentVariables.mainColor,
),
onChanged: (newValue) {
widget.questionnaires.forEach((questionnaire) {
if (questionnaire.title == newValue) {
questionnaireController.setSelectedQuestionnaire(questionnaire);
// questionnaireController.selectedQuestionnaire = questionnaire;
}
});
Future.delayed(Duration(seconds: 5), () => setState(() {
dropdownValue = questionnaireController.selectedQuestionnaire.title;
}));
//Show continue button
questionnaireController.showButton();
//Used in reminder
},
items: widget.questionnaires.map((questionnaire) {
return DropdownMenuItem(
value: questionnaire.title,
child: Text(
questionnaire.title,
style: TextStyle(color: EnvironmentVariables.secondaryColor),
),
);
}).toList(),
);
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行代码并打开弹出对话框时,出现以下错误
构建 Dropdown(dirty, state: _DropdownState#97b88) 时抛出以下断言:构建期间调用 setState() 或 markNeedsBuild()。
该 Obx 小部件无法标记为需要构建,因为框架已经在构建小部件的过程中。仅当小部件的祖先之一当前正在构建时,才可以将其标记为需要在构建阶段构建。允许此异常,因为框架在子窗口之前构建父窗口小部件,这意味着将始终构建脏后代。否则,框架可能不会在此构建阶段访问此小部件。调用 setState() 或 markNeedsBuild() 的小部件是: Obx 状态:_ObxState#d84a8 进行有问题的调用时当前正在构建的小部件是: Dropdown dirty state: _DropdownState#97b88 相关导致错误的小部件是: 落下
我的问题是,我该如何解决这个错误?我知道以下功能会有所帮助
WidgetsBinding.instance.addPostFrameCallback((_) {
// executes after build
})
Run Code Online (Sandbox Code Playgroud)
但是我应该在哪里实现上面的功能呢?
感谢您的时间
Bal*_*ram 17
如果您使用 Statefull 小部件,您可以在 initState 内进行初始化
initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
// executes after build
});
}
Run Code Online (Sandbox Code Playgroud)
需要知道:
| 归档时间: |
|
| 查看次数: |
10924 次 |
| 最近记录: |