You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中DropDownTextField无法从SQFlite设置选中值问题

Flutter中DropDownTextField无法设置数据库获取值的解决方案

问题描述

我在Flutter应用中使用sqflite作为数据库,已将下拉选项数据存储到数据表中。当尝试从数据库检索数据并设置为DropDownTextField的选中值时,虽能获取到正确的数据库数据,但无法将其设置到DropDownTextField中,且初始值也不显示。

问题分析

代码存在以下关键问题导致选中值无法生效:

  • 控制器初始化顺序错误:_cnt在_loadData之后才初始化,数据库加载时无法操作控制器
  • DropDownTextField未绑定控制器:声明了SingleValueDropDownController但未关联到组件
  • 选中值设置方式错误:仅修改_casecategoryController文本无法同步到下拉组件,需通过下拉控制器的selectValue方法操作

修复步骤

  1. 调整初始化顺序:在initState中先初始化_cnt,再调用_loadData
  2. 绑定控制器到组件:给DropDownTextField添加controller: _cnt属性
  3. 正确设置选中值:在_loadData中使用_cnt.selectValue传入对应的DropDownValueModel对象
  4. 优化初始值逻辑:确保数据加载前初始状态合理

修改后的完整代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 03:19:57