Flutter实现SQL查询后自动打开首个商品详情页的方法
实现查询后自动跳转第一个商品详情页的方案
核心思路
点击查询按钮后,先执行SQL查询获取商品列表,在查询完成且列表不为空时,自动导航到第一个商品的详情页,同时更新页面状态展示商品列表。
修改步骤及完整代码
- 在状态类中新增变量保存查询结果
- 重构按钮点击逻辑,将查询操作移至按钮点击时触发,并添加自动跳转逻辑
- 替换原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
相关产品推荐
相关产品推荐

