Flutter应用DataTable仅显示第一列数据问题求助
问题根源
你的代码核心问题在于MyCustomForm作为StatefulWidget,自身的cpsNumber、itemDescription、selectedReason getter方法都返回固定空字符串,完全没有关联到用户在表单中输入/选择的真实数据。这导致存储到SharedPreferences的字符串格式为学校名称|||(其余字段为空),汇总页拆分后自然只有第一列有内容,其余列显示为空,看起来像是只显示第一列。
另外,_MyCustomFormState中的选择原因变量和getter重名,且没有对外暴露正确的访问途径,父类无法获取到用户选择的原因。
修复步骤
修正
MyCustomForm的getter方法,关联到State的真实数据
给MyCustomForm添加GlobalKey,用来访问对应State实例中的数据,替换原来的空getter:class MyCustomForm extends StatefulWidget { final VoidCallback onCpsNumberTyped; final GlobalKey<_MyCustomFormState> formKey = GlobalKey<_MyCustomFormState>(); MyCustomForm({required this.onCpsNumberTyped}); @override _MyCustomFormState createState() => _MyCustomFormState(); String get cpsNumber => formKey.currentState?.cpsNumber ?? ''; String get itemDescription => formKey.currentState?.itemDescription ?? ''; String get selectedReason => formKey.currentState?.selectedReason ?? ''; }修正
_MyCustomFormState中的变量和getter
重命名选择原因变量避免和getter重名,并添加对应的getter暴露数据:class _MyCustomFormState extends State<MyCustomForm> { final TextEditingController _cpsNumberController = TextEditingController(); final TextEditingController _itemDescriptionController = TextEditingController(); String? _selectedReason; // 重命名变量避免冲突 bool isFirstTime = true; final List<String> _reasonsForSurplus = [ 'Obsolete Equipment', 'Replacement', 'Damage', 'Others', ]; String get cpsNumber => _cpsNumberController.text; String get itemDescription => _itemDescriptionController.text; String get selectedReason => _selectedReason ?? ''; // 添加选择原因的getter @override void initState() { super.initState(); _cpsNumberController.addListener(() { if (isFirstTime && _cpsNumberController.text.isNotEmpty) { widget.onCpsNumberTyped(); isFirstTime = false; } }); } @override void dispose() { _cpsNumberController.dispose(); _itemDescriptionController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(16.0), child: Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ TextFormField( controller: _cpsNumberController, decoration: InputDecoration( labelText: 'CPS Number', border: OutlineInputBorder(), ), ), SizedBox(height: 24.0), TextFormField( controller: _itemDescriptionController, decoration: InputDecoration( labelText: 'Item Description', border: OutlineInputBorder(), ), maxLines: null, ), SizedBox(height: 24.0), DropdownButtonFormField<String>( value: _selectedReason, // 使用重命名后的变量 decoration: InputDecoration( labelText: 'Reason for Surplus', border: OutlineInputBorder(), ), onChanged: (String? newValue) { setState(() { _selectedReason = newValue; // 更新重命名后的变量 }); }, items: _reasonsForSurplus.map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ), ], ), ), ), ); } }移除SummaryPage中的重复代码
你的代码中SummaryPage存在重复的_loadData、build和clearFormData方法,保留完整的异步实现版本即可,删除重复的空实现和冗余代码。
修复后效果
点击REVIEW按钮时,reviewData方法会正确获取到每个表单的真实输入数据,存储到SharedPreferences的字符串格式为学校名称|CPS编号|物品描述|选择原因,汇总页拆分后就能正常显示所有列的数据了。
内容的提问来源于stack exchange,提问作者djjailbreak

