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

Flutter Sqflite:如何按条件筛选数据并展示至ListView

解决Sqflite按bodyPart筛选数据并展示到ListView的问题

问题核心

你当前无法通过bodyPart字段筛选数据,主要原因包括:模型类缺失bodyPart字段、筛选方法存在未定义变量和SQL拼接风险、未正确传入筛选参数。以下是分步修复方案:


1. 完善模型类,补充bodyPart字段

原模型类未包含bodyPart字段,导致从数据库读取数据时无法映射该字段,修正后:

class UserInputModel {
  int? id;
  String? content;
  String? bodyPart;

  UserInputModel({
    this.id,
    required this.content,
    this.bodyPart,
  });

  Map<String, dynamic> toMap() {
    var map = <String,dynamic> {};
    map['id'] = id;
    map['content'] = content;
    map['bodyPart'] = bodyPart;
    return map;
  }

  factory UserInputModel.fromMap(Map<String, dynamic> map) => UserInputModel(
    id: map['id'],
    content: map['content'],
    bodyPart: map['bodyPart'],
  );
}

2. 修复数据库筛选方法,使用参数化查询

原fetchDesiredData方法存在未定义变量和SQL注入风险,改用sqflite的query方法实现安全筛选:

// 替换数据库助手类中的fetchDesiredData方法
static Future<List<UserInputModel>> fetchDesiredData(String targetBodyPart) async {
  final db = await MeasurementsDBHelper.db();
  final result = await db.query(
    tableName,
    where: "$columnBodyPart = ?",
    whereArgs: [targetBodyPart], // 参数化查询自动处理字符串格式,避免类型不匹配
    orderBy: "$columnId DESC",
  );
  return result.map((map) => UserInputModel.fromMap(map)).toList();
}

3. 页面调用筛选方法并展示ListView

以"手臂"页面为例,实现对应bodyPart的数据加载和展示:

class ArmMeasurementsPage extends StatefulWidget {
  const ArmMeasurementsPage({super.key});

  @override
  State<ArmMeasurementsPage> createState() => _ArmMeasurementsPageState();
}

class _ArmMeasurementsPageState extends State<ArmMeasurementsPage> {
  List<UserInputModel> _filteredData = [];

  @override
  void initState() {
    super.initState();
    _loadFilteredMeasurements();
  }

  Future<void> _loadFilteredMeasurements() async {
    // 传入当前页面对应的bodyPart值,比如"手臂"
    final data = await MeasurementsDBHelper.fetchDesiredData("手臂");
    setState(() {
      _filteredData = data;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("手臂测量记录")),
      body: ListView.builder(
        itemCount: _filteredData.length,
        itemBuilder: (context, index) {
          final item = _filteredData[index];
          return ListTile(
            title: Text(item.content ?? ""),
            subtitle: Text(item.bodyPart ?? ""),
            trailing: IconButton(
              icon: const Icon(Icons.delete),
              onPressed: () async {
                if (item.id != null) {
                  await MeasurementsDBHelper.deleteMeasurement(item.id!);
                  _loadFilteredMeasurements(); // 删除后刷新列表
                }
              },
            ),
          );
        },
      ),
    );
  }
}

4. 排查注意事项

  • 确保插入数据时的bodyPart值与筛选时传入的完全一致(注意大小写、空格等细节)
  • 可使用数据库查看工具(如SQLiteStudio)确认数据库中bodyPart字段的实际存储值
  • 始终使用参数化查询(whereArgs),避免直接拼接SQL语句,防止注入风险和类型不匹配问题

内容的提问来源于stack exchange,提问作者user22187566

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:35:12