Flutter中Navigator.of(context).pop()引发黑屏问题及表单重置需求
解决Flutter表单提交后黑屏及无法重置的问题
让我们一步步搞定你的问题:
问题根源
- 黑屏现象:你在提交成功后调用了
Navigator.of(context).pop();,而当前页面是App的首页(home: MyApp()),弹出这个页面后没有其他页面可以显示,直接导致了黑屏。 - 无法重置表单:提交完成后没有重置下拉框的选中状态和输入框内容,表单一直停留在之前的输入状态,没法直接接收新的用户输入。
解决方案
我们需要做这几个核心修改:
- 删掉导致页面被弹出的
Navigator.of(context).pop();代码 - 提交成功后重置所有表单控件的状态(下拉框选中值、输入框文本)
- 可选添加提交成功提示,提升用户体验
修改后的完整代码
import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_core/firebase_core.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); runApp(const MaterialApp(home: MyApp())); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { final TextEditingController problemBox = TextEditingController(); final db = FirebaseFirestore.instance; final List<String> _listItem = ["Category 1", "Category 2", "Category 3", "Category 4"]; final List<String> _listItem1 = [ "Sub Category 1", "Sub Category 2", "Sub Category 3", "Sub Category 4" ]; final List<String> _listItem2 = ["CRIS", "ADMINISTRATION", "ZONE", "DEPARTMENT"]; String? dropdownValue; String? dropdownValue1; String? dropdownValue2; final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, appBar: AppBar( title: const Text("Feedback"), centerTitle: true, leading: IconButton( onPressed: () {}, icon: const Icon(Icons.home), ), ), body: Container( child: Center( child: SingleChildScrollView( child: Form( autovalidateMode: AutovalidateMode.onUserInteraction, key: _formKey, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ const Flexible(child: Text("CATEGORY")), const Flexible( child: RichText( textAlign: TextAlign.center, text: TextSpan( children: <TextSpan>[ TextSpan( text: '*', style: TextStyle(color: Colors.red), ), ], ), )), const SizedBox(width: 30), Flexible( child: DropdownButtonFormField<String>( isExpanded: true, hint: const Text("Select"), value: dropdownValue, validator: (value) => value == null ? "Please select a value" : null, items: _listItem .map<DropdownMenuItem<String>>((valueItem) { return DropdownMenuItem<String>( value: valueItem, child: Text(valueItem), ); }).toList(), onChanged: (value) { setState(() { dropdownValue = value; }); }, )), ], ), const SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ const Flexible(child: Text("SUB-CATEGORY")), const Flexible( child: RichText( textAlign: TextAlign.center, text: TextSpan( children: <TextSpan>[ TextSpan( text: '*', style: TextStyle(color: Colors.red), ), ], ), )), const SizedBox(width: 30), Flexible( child: DropdownButtonFormField<String>( isExpanded: true, hint: const Text("Select"), value: dropdownValue1, validator: (value) => value == null ? "Please select a value" : null, items: _listItem1 .map<DropdownMenuItem<String>>((valueItem1) { return DropdownMenuItem<String>( value: valueItem1, child: Text(valueItem1), ); }).toList(), onChanged: (value) { setState(() { dropdownValue1 = value; }); }, )), ], ), const SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ const Flexible(child: Text("MARKED TO")), const Flexible( child: RichText( text: TextSpan( children: <TextSpan>[ TextSpan( text: '*', style: TextStyle(color: Colors.red), ), ], ), )), const SizedBox(width: 30), Flexible( child: DropdownButtonFormField<String>( isExpanded: true, hint: const Text("Select"), value: dropdownValue2, validator: (value) => value == null ? "Please select a value" : null, items: _listItem2 .map<DropdownMenuItem<String>>((valueItem2) { return DropdownMenuItem<String>( value: valueItem2, child: Text(valueItem2), ); }).toList(), onChanged: (value) { setState(() { dropdownValue2 = value; }); }, )), ], ), const SizedBox(height: 10), Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Padding( padding: const EdgeInsets.fromLTRB(70, 00, 70, 00), child: TextFormField( validator: (String? value) { if (value == null || value.isEmpty) { return "Description is required"; } return null; }, controller: problemBox, decoration: const InputDecoration( hintText: "Describe your problem here.", ), maxLength: 1000, maxLines: 5, ), ) ], ), const SizedBox(height: 10), ButtonTheme( child: ElevatedButton( child: const Text("Submit"), onPressed: () async { if (_formKey.currentState!.validate()) { print("Form is validated"); // 提交数据到Firestore await db.collection("COLLECTION").add({ "CATEGORY": dropdownValue, "SUB-CATEGORY": dropdownValue1, "MARKED TO": dropdownValue2, "PROBLEM": problemBox.text, }); // 重置表单状态 setState(() { dropdownValue = null; dropdownValue1 = null; dropdownValue2 = null; problemBox.clear(); }); // 显示提交成功提示 ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("Feedback submitted successfully!")), ); } }, style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric( horizontal: 25, vertical: 15), ), ), ), ]), ), )), )); } }
关键修改点说明
- 移除
Navigator.pop():彻底解决黑屏问题,不再弹出当前页面 - 表单重置逻辑:提交成功后通过
setState将所有下拉框选中值设为null,并调用problemBox.clear()清空输入框,让表单回到初始可输入状态 - 添加SnackBar提示:给用户明确的提交成功反馈,避免用户重复提交
- 代码优化:对变量类型做了空安全处理(比如
String?),让代码更符合Flutter最佳实践
内容的提问来源于stack exchange,提问作者Bhaskar2510
相关产品推荐
相关产品推荐

