Flutter中DropDownTextField无法从SQFlite设置选中值问题
Flutter中DropDownTextField无法设置数据库获取值的解决方案
问题描述
我在Flutter应用中使用sqflite作为数据库,已将下拉选项数据存储到数据表中。当尝试从数据库检索数据并设置为DropDownTextField的选中值时,虽能获取到正确的数据库数据,但无法将其设置到DropDownTextField中,且初始值也不显示。
问题分析
代码存在以下关键问题导致选中值无法生效:
- 控制器初始化顺序错误:
_cnt在_loadData之后才初始化,数据库加载时无法操作控制器 - DropDownTextField未绑定控制器:声明了
SingleValueDropDownController但未关联到组件 - 选中值设置方式错误:仅修改
_casecategoryController文本无法同步到下拉组件,需通过下拉控制器的selectValue方法操作
修复步骤
- 调整初始化顺序:在
initState中先初始化_cnt,再调用_loadData - 绑定控制器到组件:给DropDownTextField添加
controller: _cnt属性 - 正确设置选中值:在
_loadData中使用_cnt.selectValue传入对应的DropDownValueModel对象 - 优化初始值逻辑:确保数据加载前初始状态合理
修改后的完整代码
import 'package:flutter/material.dart'; import 'package:adv_flutter/pages/casecategorylist.dart'; import 'package:adv_flutter/pages/database_helper.dart'; import 'package:dropdown_textfield/dropdown_textfield.dart'; import 'package:sqflite/sqflite.dart'; class NoticeBoard extends StatefulWidget { const NoticeBoard({super.key}); @override State<NoticeBoard> createState() => _NoticeBoardState(); } class _NoticeBoardState extends State<NoticeBoard> { final TextStyle lable_name = TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: Colors.black54); final TextStyle heading_name = TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.blue); late SingleValueDropDownController _cnt; TextEditingController _casenoController = TextEditingController(); TextEditingController _casecategoryController = TextEditingController(); String caseNo = 'RCS/22/04/2024'; @override void initState() { // 先初始化控制器,再加载数据 _cnt = SingleValueDropDownController(); _loadData(caseNo); super.initState(); } Future<void> _loadData(String caseNo) async { try { Database db = await openDatabase('add.db'); List<Map<String, dynamic>> caseData = await db .rawQuery("SELECT * FROM newcase WHERE case_no = ?", [caseNo]); if (caseData.isNotEmpty) { setState(() { _casenoController.text = caseData[0]['case_no']; String category = caseData[0]['category']; _casecategoryController.text = category; print("Category from database: $category"); // 通过控制器设置选中值,需要传入DropDownValueModel对象 if (case_category.contains(category)) { _cnt.selectValue(DropDownValueModel(name: category, value: category)); } }); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('No data found for case number: $caseNo'), duration: Duration(seconds: 2), ), ); } } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Error loading data for case number: $caseNo'), duration: Duration(seconds: 2), ), ); } } Future<void> updatecaseData(String caseNo) async { final db = await DatabaseHelper.instance.database; await db.update( 'newcase', { 'category': _casecategoryController.text, }, where: 'case_no = ?', whereArgs: [caseNo], ); addCasemsg(); } void addCasemsg() { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Case updated successfuly!!'), duration: Duration(seconds: 2), ), ); } @override void dispose() { _cnt.dispose(); super.dispose(); } Container LabelNameContainer( {required String labelText, Alignment? myAlignment}) { return Container( width: 80, height: 50, padding: EdgeInsets.symmetric(horizontal: 8), child: Align( alignment: myAlignment ?? Alignment.bottomCenter, child: Text(labelText, style: lable_name), ), ); } @override Widget build(BuildContext context) => Scaffold( resizeToAvoidBottomInset: false, appBar: AppBar( iconTheme: IconThemeData(color: Colors.white), title: Text( 'Edit Noticeboard Detail', style: TextStyle(color: Colors.white), ), backgroundColor: Colors.black, ), backgroundColor: Color.fromRGBO(245, 245, 245, 1), body: SingleChildScrollView( child: Center( child: Align( alignment: Alignment.topCenter, child: Container( padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 8), Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Row( children: [ LabelNameContainer(labelText: "Case No."), Flexible( child: Text(_casenoController .text), // Fixed: Accessing controller's text value ), ], ), SizedBox(height: 8), Row( children: [ LabelNameContainer(labelText: "Category"), Flexible( child: DropDownTextField( // 绑定控制器 controller: _cnt, enableSearch: true, dropdownColor: Colors.white, dropdownRadius: 0, dropDownIconProperty: IconProperty( icon: Icons.keyboard_arrow_down_sharp), textFieldDecoration: InputDecoration( hintStyle: TextStyle( fontSize: 14, color: Colors.black26), hintText: 'Select case category', contentPadding: EdgeInsets.only(top: 20), errorBorder: UnderlineInputBorder( borderSide: BorderSide( width: 2, color: Colors.red.shade800)), focusedBorder: UnderlineInputBorder( borderSide: BorderSide( width: 2, color: Colors.blue.shade900)), ), searchDecoration: InputDecoration( hintText: 'Search category'), dropDownItemCount: 7, listPadding: ListPadding(top: 5, bottom: 5), listTextStyle: TextStyle( fontSize: 16, fontWeight: FontWeight.w500), dropDownList: case_category .map((category) => DropDownValueModel( name: category, value: category)) .toList(), // 初始值可留空,由控制器控制 initialValue: null, onChanged: (selectedCategoryModel) { if (selectedCategoryModel != null && selectedCategoryModel is DropDownValueModel) { setState(() { _casecategoryController.text = selectedCategoryModel.value; }); } }, ), ), ], ), ], ), SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ SizedBox( width: 130, child: ElevatedButton( onPressed: () { updatecaseData(caseNo); }, style: ButtonStyle( backgroundColor: MaterialStateProperty.all<Color>(Colors.blue), shape: MaterialStateProperty.all< RoundedRectangleBorder>( RoundedRectangleBorder( borderRadius: BorderRadius.circular(4.0), ), ), ), child: Text( "Update", style: TextStyle(color: Colors.white), ), ), ), SizedBox(width: 8), // Add horizontal spacing SizedBox( width: 130, child: ElevatedButton( onPressed: () { Navigator.pop(context); }, style: ButtonStyle( backgroundColor: MaterialStateProperty.all<Color>(Colors.blue), shape: MaterialStateProperty.all< RoundedRectangleBorder>( RoundedRectangleBorder( borderRadius: BorderRadius.circular(4.0), ), ), ), child: Text( "Done", style: TextStyle(color: Colors.white), ), ), ), ], ) ], ), ), ), ), ), ); }
内容的提问来源于stack exchange,提问作者RAHUL THAKRANI
相关产品推荐
相关产品推荐

