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

Flutter中如何通过ID获取特定数据并在ListView展示

需求:通过ID获取特定数据并在ListView展示

我已经在Flutter项目中用sqflite实现了数据的查看、插入、删除及更新操作,现在需要实现通过ID获取特定数据并在ListView中展示,以下是我的现有代码:

main.dart 文件

class _SqliteAppState extends State<SqliteApp> {
  int? selectedId;
  final textController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: TextField(
            controller: textController,
          ),
        ),
        body: Center(
          child: FutureBuilder<List<Grocery>>(
              future: DatabaseHelper.instance.getGroceries(),
              builder: (BuildContext context,
                  AsyncSnapshot<List<Grocery>> snapshot) {
                if (!snapshot.hasData) {
                  return Center(child: Text('Loading...'));
                }
                return snapshot.data!.isEmpty
                    ? Center(child: Text('No Groceries in List.'))
                    : ListView(
                        children: snapshot.data!.map((grocery) {
                          return Center(
                            child: Card(
                              color: selectedId == grocery.id
                                  ? Colors.white70
                                  : Colors.white,
                              child: ListTile(
                                title: Text(grocery.name),
                                onTap: () {
                                  setState(() {
                                    if (selectedId == null) {
                                      textController.text = grocery.name;
                                      selectedId = grocery.id;
                                    } else {
                                      textController.text = '';
                                      selectedId = null;
                                    }
                                  });
                                },
                                onLongPress: () {
                                  setState(() {
                                    DatabaseHelper.instance.remove(grocery.id!);
                                  });
                                },
                              ),
                            ),
                          );
                        }).toList(),
                      );
              }),
        ),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.save),
          onPressed: () async {
            selectedId != null
                ? await DatabaseHelper.instance.update(
                    Grocery(id: selectedId, name: textController.text),
                  )
                : await DatabaseHelper.instance.add(
                    Grocery(name: textController.text),
                  );
            setState(() {
              textController.clear();
              selectedId = null;
            });
          },
        ),
      ),
    );
  }
}

模型类代码

class Grocery {
  int? id;
  String name;

  Grocery({this.id, required this.name});

  factory Grocery.fromMap(Map<String, dynamic> json) => Grocery(
        id: json['id'],
        name: json['name'],
      );

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'name': name,
    };
  }
}

DatabaseHelper类代码

class DatabaseHelper {
  DatabaseHelper._privateConstructor();
  static final DatabaseHelper instance = DatabaseHelper._privateConstructor();

  static Database? _database;
  Future<Database> get database async => _database ??= await _initDatabase();

  Future<Database> _initDatabase() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, 'groceries.db');
    return await openDatabase(
      path,
      version: 1,
      onCreate: _onCreate,
    );
  }

  Future _onCreate(Database db, int version) async {
    await db.execute('''
      CREATE TABLE groceries(
          id INTEGER PRIMARY KEY,
          name TEXT
      )
      ''');
  }

  Future<List<Grocery>> getGroceries() async {
    Database db = await instance.database;
    var groceries = await db.query('groceries', orderBy: 'name');
    List<Grocery> groceryList = groceries.isNotEmpty
        ? groceries.map((c) => Grocery.fromMap(c)).toList()
        : [];
    return groceryList;
  }

  Future<int> add(Grocery grocery) async {
    Database db = await instance.database;
    return await db.insert('groceries', grocery.toMap());
  }

  Future<int> remove(int id) async {
    Database db = await instance.database;
    return await db.delete('groceries', where: 'id = ?', whereArgs: [id]);
  }

  Future<int> update(Grocery grocery) async {
    Database db = await instance.database;
    return await db.update('groceries', grocery.toMap(),
        where: "id = ?", whereArgs: [grocery.id]);
  }
}

实现方案

1. 在DatabaseHelper中添加通过ID查询单条数据的方法

在DatabaseHelper类里新增方法,用于根据ID获取指定的Grocery数据:

Future<Grocery?> getGroceryById(int id) async {
  Database db = await instance.database;
  var result = await db.query('groceries', where: 'id = ?', whereArgs: [id]);
  return result.isNotEmpty ? Grocery.fromMap(result.first) : null;
}

2. 修改页面逻辑实现数据展示

以下示例实现两种查询展示方式:点击列表项自动查询展示单条数据,或手动输入ID查询展示。

修改_SqliteAppState代码:

class _SqliteAppState extends State<SqliteApp> {
  int? selectedId;
  Grocery? selectedGrocery; // 存储选中的单条数据
  final textController = TextEditingController();
  final idQueryController = TextEditingController(); // 手动输入ID的控制器

  // 根据ID获取数据的方法
  Future<void> fetchGroceryById(int id) async {
    Grocery? grocery = await DatabaseHelper.instance.getGroceryById(id);
    setState(() {
      selectedGrocery = grocery;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Row(
            children: [
              Expanded(
                child: TextField(
                  controller: textController,
                  decoration: const InputDecoration(hintText: '输入商品名称'),
                ),
              ),
              const SizedBox(width: 10),
              Expanded(
                child: TextField(
                  controller: idQueryController,
                  decoration: const InputDecoration(hintText: '输入ID查询'),
                  keyboardType: TextInputType.number,
                ),
              ),
              ElevatedButton(
                onPressed: () {
                  if (idQueryController.text.isNotEmpty) {
                    fetchGroceryById(int.parse(idQueryController.text));
                  }
                },
                child: const Text('查询'),
              )
            ],
          ),
        ),
        body: Column(
          children: [
            // 展示通过ID查询到的单条数据
            if (selectedGrocery != null)
              Card(
                margin: const EdgeInsets.all(16),
                child: Padding(
                  padding: const EdgeInsets.all(16),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text('ID: ${selectedGrocery!.id}'),
                      const SizedBox(height: 8),
                      Text('商品名称: ${selectedGrocery!.name}'),
                    ],
                  ),
                ),
              ),
            // 原有商品列表
            Expanded(
              child: FutureBuilder<List<Grocery>>(
                  future: DatabaseHelper.instance.getGroceries(),
                  builder: (BuildContext context,
                      AsyncSnapshot<List<Grocery>> snapshot) {
                    if (!snapshot.hasData) {
                      return const Center(child: Text('加载中...'));
                    }
                    return snapshot.data!.isEmpty
                        ? const Center(child: Text('列表为空'))
                        : ListView(
                            children: snapshot.data!.map((grocery) {
                              return Center(
                                child: Card(
                                  color: selectedId == grocery.id
                                      ? Colors.white70
                                      : Colors.white,
                                  child: ListTile(
                                    title: Text(grocery.name),
                                    onTap: () {
                                      setState(() {
                                        textController.text = grocery.name;
                                        selectedId = grocery.id;
                                        // 点击列表项时自动查询该ID的数据
                                        fetchGroceryById(grocery.id!);
                                      });
                                    },
                                    onLongPress: () {
                                      setState(() {
                                        DatabaseHelper.instance.remove(grocery.id!);
                                      });
                                    },
                                  ),
                                ),
                              );
                            }).toList(),
                          );
                  }),
            ),
          ],
        ),
        floatingActionButton: FloatingActionButton(
          child: const Icon(Icons.save),
          onPressed: () async {
            selectedId != null
                ? await DatabaseHelper.instance.update(
                    Grocery(id: selectedId, name: textController.text),
                  )
                : await DatabaseHelper.instance.add(
                    Grocery(name: textController.text),
                  );
            setState(() {
              textController.clear();
              selectedId = null;
              selectedGrocery = null; // 清空选中数据
            });
          },
        ),
      ),
    );
  }
}

3. 逻辑说明

  • getGroceryById方法通过db.query指定where条件查询单条数据,无匹配时返回null。
  • 页面新增了手动输入ID查询的功能,同时保留点击列表项自动查询展示的逻辑。
  • 查询到的单条数据会在列表上方以卡片形式展示,直观呈现对应ID的商品信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 07:20:29