Flutter技术求助:API返回数据无法渲染到Scaffold容器
问题排查与修复
你的代码存在几个关键问题导致数据无法渲染,逐一说明:
- 全局
parse变量未被赋值:API请求返回的数据从未存入这个变量,parsePinCode里的final parse是局部变量,和全局的parse毫无关联,所以UI始终显示空内容。 - 未处理异步请求结果:按钮点击时调用
getPincode但没加await,无法获取实际返回值,更无法更新到变量中。 - 未触发UI更新:即使获取到数据,也没调用
setState通知Flutter框架重建UI,所以UI不会刷新显示新数据。 - TextEditingController位置错误:把控制器放在
build方法里,每次UI重建都会重新创建,导致输入状态丢失,应该移到State类的成员变量位置。
修改后的完整代码
import 'dart:convert'; import 'package:api/model/pin_code.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { // 存储API返回的邮编数据,初始为空 List<PinCode> pinCodeData = []; // 将控制器移到State成员变量,避免重建丢失状态 final TextEditingController pinCodeController = TextEditingController(); Future<List<PinCode>> getPincode(String pincode) async { var response = await http .get(Uri.parse('https://api.postalpincode.in/pincode/${pincode}')); return compute(parsePinCode, response.body); } List<PinCode> parsePinCode(String responseBody) { final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>(); return parsed.map<PinCode>((json) => PinCode.fromJson(json)).toList(); } @override Widget build(BuildContext context) { double height = MediaQuery.of(context).size.height; double width = MediaQuery.of(context).size.width; return Scaffold( backgroundColor: Colors.white, appBar: AppBar( title: const Text('Pin code Rest API Demo '), ), body: Column( children: [ SizedBox(height: height * 0.09), TextFormField( controller: pinCodeController, keyboardType: TextInputType.number, decoration: const InputDecoration( hintText: '输入邮编', border: OutlineInputBorder(), ), ), SizedBox(height: height * 0.05), ElevatedButton( onPressed: () async { if (pinCodeController.text.isEmpty) return; // await获取异步结果 final data = await getPincode(pinCodeController.text); // 调用setState更新UI setState(() { pinCodeData = data; }); }, child: const Text("Search"), ), const SizedBox(height: 20), Container( color: Colors.blue, padding: const EdgeInsets.all(16), child: pinCodeData.isEmpty ? const Text('请输入邮编查询') : Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('状态: ${pinCodeData[0].status}'), Text('邮编: ${pinCodeData[0].postOffice?[0].pincode}'), Text('地区: ${pinCodeData[0].postOffice?[0].name}'), Text('城市: ${pinCodeData[0].postOffice?[0].city}'), Text('州: ${pinCodeData[0].postOffice?[0].state}'), ], ), ) ], ), ); } @override void dispose() { // 销毁控制器,避免内存泄漏 pinCodeController.dispose(); super.dispose(); } }
关键修改点说明
- 变量类型修正:把原来的
Map parse改成List<PinCode> pinCodeData,因为API返回的是数组结构,和parsePinCode返回的类型一致。 - 控制器移到成员变量:避免每次build重建控制器,同时在dispose里销毁它防止内存泄漏。
- 异步请求处理:按钮点击时用
await获取getPincode的返回值,然后调用setState更新pinCodeData,触发UI重建。 - UI内容优化:蓝色容器里根据
pinCodeData是否为空显示不同内容,同时展示具体的邮编信息,而不是直接打印对象。 - 移除冗余代码:删除
parsePinCode里的局部parse变量,因为它没有实际作用。
内容的提问来源于stack exchange,提问作者Linisha
相关产品推荐
相关产品推荐

