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

Flutter实现SQL查询后自动打开首个商品详情页的方法

实现查询后自动跳转第一个商品详情页的方案

核心思路

点击查询按钮后,先执行SQL查询获取商品列表,在查询完成且列表不为空时,自动导航到第一个商品的详情页,同时更新页面状态展示商品列表。

修改步骤及完整代码

  1. 在状态类中新增变量保存查询结果
  2. 重构按钮点击逻辑,将查询操作移至按钮点击时触发,并添加自动跳转逻辑
  3. 替换原FutureBuilder为基于查询结果的条件渲染,避免重复查询

修改后的完整代码:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:sql_app/dita_conveer.dart';
import 'package:sql_app/info_produs.dart';
import 'package:sql_conn/sql_conn.dart';
import 'info_produs.dart';

class ditaStatie extends StatefulWidget {
  final String nrStatie;
  const ditaStatie({Key? key, required this.nrStatie}) : super(key: key);

  @override
  State<ditaStatie> createState() => _ditaStatieState();
}

class _ditaStatieState extends State<ditaStatie> {
  final _scanCutieController = TextEditingController();
  bool vizibil = true;
  String cutieScan = '';
  // 新增变量保存查询结果
  List? _productsData;

  @override
  void dispose() {
    _scanCutieController.dispose();
    super.dispose();
  }

  Future<List?> read(String query) async {
    final result = await SqlConn.readData(query);
    List _list = jsonDecode(result) as List;
    return _list;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          SizedBox(height: 30),
          Padding(
            padding: const EdgeInsets.all(10),
            child: Visibility(
              visible: vizibil,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  Expanded(
                    flex: 6,
                    child: TextFormField(
                      controller: _scanCutieController,
                      decoration: const InputDecoration(
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.all(Radius.circular(20)),
                            borderSide: BorderSide(
                              color: Colors.redAccent,
                              width: 3,
                            )),
                        hintText: 'Scaneaza BarCode',
                      ),
                    ),
                  ),
                  const SizedBox(width: 10),
                  Expanded(
                    flex: 2,
                    child: ElevatedButton(
                        child: const Text('Test'),
                        onPressed: () async {
                          setState(() {
                            vizibil = false;
                            cutieScan = _scanCutieController.text;
                            _productsData = null; // 重置数据,显示加载状态
                          });

                          try {
                            // 执行SQL查询
                            List? data = await read(
                                "SELECT ProductAdress, ProductName, NeedCount, ScanCount, ProductAdress, ProductBarCode, ProductSeriesCount, ProductExpirationDate FROM ScanRest WHERE ProductStation = '${widget.nrStatie}' AND BoxID = '${cutieScan}' ORDER BY ProductName ASC;");
                            
                            setState(() {
                              _productsData = data;
                            });

                            // 若查询结果不为空,自动跳转第一个商品详情页
                            if (data != null && data.isNotEmpty) {
                              Map firstProduct = data[0] as Map;
                              Navigator.push(
                                context,
                                MaterialPageRoute(
                                  builder: (context) => InfoProdus(
                                    denumProdus: firstProduct['ProductName'].toString(),
                                    adresaProdus: firstProduct['ProductAdress'].toString(),
                                    needCount: firstProduct['NeedCount'].toString(),
                                    scanCount: firstProduct['ScanCount'].toString(),
                                    dataExpirare: firstProduct['ProductExpirationDate'].toString(),
                                    productBarCode: firstProduct['ProductBarCode'].toString(),
                                    productSeriesCount: firstProduct['ProductSeriesCount'].toString(),
                                  ),
                                ),
                              );
                            }
                          } catch (e) {
                            setState(() {
                              _productsData = [];
                            });
                            // 显示错误提示
                            ScaffoldMessenger.of(context).showSnackBar(
                              SnackBar(content: Text('查询出错:$e')),
                            );
                          }
                        }),
                  ),
                ],
              ),
            ),
          ),
          Visibility(
            visible: !vizibil,
            child: Row(
              children: const [
                Expanded(flex: 2, child: Text('Adresa')),
                Expanded(flex: 5, child: Text('Denumirea Produs')),
                Expanded(flex: 2, child: Text('Comandat')),
                Expanded(flex: 2, child: Text('Scanat')),
              ],
            ),
          ),
          Expanded(
            child: _productsData == null
                ? const Text('Loading....')
                : _productsData!.isEmpty
                    ? const Text('No products found')
                    : ListView.builder(
                        itemCount: _productsData!.length,
                        itemBuilder: (context, index) {
                          Map product = _productsData![index] as Map;
                          return Card(
                            elevation: 2,
                            child: GestureDetector(
                              onTap: () {
                                Navigator.push(
                                  context,
                                  MaterialPageRoute(
                                    builder: (context) => InfoProdus(
                                      denumProdus: product['ProductName'].toString(),
                                      adresaProdus: product['ProductAdress'].toString(),
                                      needCount: product['NeedCount'].toString(),
                                      scanCount: product['ScanCount'].toString(),
                                      dataExpirare: product['ProductExpirationDate'].toString(),
                                      productBarCode: product['ProductBarCode'].toString(),
                                      productSeriesCount: product['ProductSeriesCount'].toString(),
                                    ),
                                  ),
                                );
                              },
                              child: Row(children: [
                                Expanded(
                                  flex: 2,
                                  child: Text(product['ProductAdress'].toString()),
                                ),
                                Expanded(
                                  flex: 5,
                                  child: Text(product['ProductName'].toString()),
                                ),
                                Expanded(
                                  flex: 2,
                                  child: Center(
                                    child: Text(product['NeedCount'].toString()),
                                  ),
                                ),
                                Expanded(
                                  flex: 2,
                                  child: Center(
                                    child: Text(product['ScanCount'].toString()),
                                  ),
                                ),
                              ]),
                            ),
                          );
                        },
                      ),
          ),
          SizedBox(
            width: double.infinity,
            child: ElevatedButton(
              style: ButtonStyle(
                  backgroundColor:
                      MaterialStateProperty.all<Color>(Colors.green)),
              child: Text(widget.nrStatie, style: const TextStyle(fontSize: 20)),
              onPressed: () => Navigator.push(context,
                  MaterialPageRoute(builder: (context) => statieConveer())),
            ),
          ),
        ],
      ),
    );
  }
}

关键修改说明

  • 将SQL查询从FutureBuilder的自动执行改为按钮点击时手动触发,精准控制查询完成后的跳转逻辑
  • 新增_productsData变量缓存查询结果,避免页面重建时重复发起SQL请求
  • 在查询完成后,判断结果不为空则直接调用Navigator.push跳转第一个商品的详情页
  • 增加try-catch捕获查询错误,通过SnackBar提示用户,提升体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:20:49