Dart/Flutter:如何将TextField值传入Service类并实现API数据展示
实现方案
1. 改造Service层方法,支持传入产品编码
先把硬编码的产品编码改成参数传入,让接口可以动态获取不同编码的数据:
Future<ProductModel?> getSingleProductData(String productCode) async { ProductModel? result; try { final response = await http.get( Uri.parse( "http://192.168.1.5/v1/api/product/read_single.php?productcode=$productCode"), headers: { HttpHeaders.contentTypeHeader: "application/json", }, ); if (response.statusCode == 200) { final item = json.decode(response.body); result = ProductModel.fromJson(item); } else { print("请求失败,状态码:${response.statusCode}"); } } catch (e) { log(e.toString()); } return result; }
2. 更新数据逻辑类,传递产品编码参数
修改DataClass的方法,让它接收产品编码并传给Service:
class DataClass extends ChangeNotifier { ProductModel? product; bool loading = false; // 新增productCode参数 getProductData(String productCode) async { loading = true; notifyListeners(); // 先通知加载状态,让UI显示加载中 product = await getSingleProductData(productCode); loading = false; notifyListeners(); } }
去掉了强制解包!,避免空指针崩溃,毕竟接口可能返回null
3. 实现TextField自动填充+跳转逻辑
在main.dart里给TextEditingController设置默认值实现自动填充,再添加跳转按钮或回车提交的逻辑:
class _MainPageState extends State<MainPage> { // 初始化时设置默认值,实现自动填充 final _textController = TextEditingController(text: "PRD89473320"); final _textNode = FocusNode(); @override void dispose() { _textController.dispose(); _textNode.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ TextField( autofocus: true, controller: _textController, focusNode: _textNode, decoration: const InputDecoration( border: OutlineInputBorder(), ), // 按回车直接跳转 onSubmitted: (_) => _goToSecondScreen(), ), const SizedBox(height: 16), ElevatedButton( onPressed: _goToSecondScreen, child: const Text("查看产品详情"), ) ], ), ), ); } void _goToSecondScreen() { final code = _textController.text.trim(); if (code.isNotEmpty) { Navigator.push( context, MaterialPageRoute( builder: (context) => SecondScreen(productCode: code), ), ); } else { // 提示用户输入编码 ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("请输入有效的产品编码")), ); } } }
4. 修改第二页面,接收编码并加载对应数据
让SecondScreen接收产品编码参数,在初始化时调用数据加载方法:
class SecondScreen extends StatefulWidget { final String productCode; const SecondScreen({super.key, required this.productCode}); @override State<SecondScreen> createState() => _SecondScreenState(); } class _SecondScreenState extends State<SecondScreen> { @override void initState() { super.initState(); final dataClass = Provider.of<DataClass>(context, listen: false); // 传入当前产品编码加载数据 dataClass.getProductData(widget.productCode); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("产品详情")), body: Consumer<DataClass>( builder: (context, data, child) { if (data.loading) { return const Center(child: CircularProgressIndicator()); } if (data.product == null) { return const Center(child: Text("未找到对应产品")); } // 根据你的ProductModel字段展示数据,示例如下 return Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("产品编码:${data.product!.productCode}"), Text("产品名称:${data.product!.productName}"), // 其他字段按需添加 ], ), ); }, ), ); } }
额外提醒
- 确保
ProductModel的fromJson方法能正确解析API返回的JSON结构 - 记得在main函数中初始化Provider:
void main() { runApp( ChangeNotifierProvider( create: (context) => DataClass(), child: const MyApp(), ), ); }
内容的提问来源于stack exchange,提问作者Abd Domingos
相关产品推荐
相关产品推荐

