Flutter调用Coinlore API无法显示数据问题求助
Flutter调用Coinlore接口加载失败排查与解决
一、先检查基础配置
- 网络权限:
- Android:在
android/app/src/main/AndroidManifest.xml中添加<uses-permission android:name="android.permission.INTERNET"/> - iOS:在
ios/Runner/Info.plist中添加NSAppTransportSecurity配置,允许HTTP请求(Coinlore接口为HTTP协议):<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
- Android:在
- 验证接口可用性:用浏览器或Postman打开
https://api.coinlore.net/api/tickers/,确认能返回正常JSON数据。
二、修复请求类(Peticion)常见问题
很多新手会忽略接口的JSON结构(接口返回外层包含data数组的对象),或未正确处理异常。以下是正确的请求类示例:
import 'dart:convert'; import 'package:http/http.dart' as http; import 'crypto_model.dart'; class Peticion { static const String baseUrl = "https://api.coinlore.net/api/tickers/"; static Future<List<Crypto>> getCryptos() async { try { final response = await http.get(Uri.parse(baseUrl)); if (response.statusCode == 200) { final Map<String, dynamic> responseData = json.decode(response.body); final List<dynamic> cryptoJsonList = responseData['data']; return cryptoJsonList.map((json) => Crypto.fromJson(json)).toList(); } else { throw Exception("请求失败,状态码:${response.statusCode}"); } } catch (e) { throw Exception("网络错误:$e"); } } }
三、适配Crypto模型类与接口字段
Coinlore返回的字段为下划线命名(如price_usd),模型类需严格对应,避免解析失败:
class Crypto { final String id; final String symbol; final String name; final String priceUsd; Crypto({ required this.id, required this.symbol, required this.name, required this.priceUsd, }); factory Crypto.fromJson(Map<String, dynamic> json) { return Crypto( id: json['id'] ?? "", symbol: json['symbol'] ?? "", name: json['name'] ?? "", priceUsd: json['price_usd'] ?? "0", ); } }
四、修正主页面的FutureBuilder使用
常见错误是在build方法中直接调用请求方法,导致页面重建时重复请求,或未处理错误状态。正确写法:
import 'package:flutter/material.dart'; import 'peticion.dart'; import 'crypto_model.dart'; class CryptoPage extends StatefulWidget { const CryptoPage({super.key}); @override State<CryptoPage> createState() => _CryptoPageState(); } class _CryptoPageState extends State<CryptoPage> { late Future<List<Crypto>> _cryptoFuture; @override void initState() { super.initState(); _cryptoFuture = Peticion.getCryptos(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("加密货币行情")), body: FutureBuilder<List<Crypto>>( future: _cryptoFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { return Center(child: Text("加载失败:${snapshot.error}")); } else if (snapshot.data == null || snapshot.data!.isEmpty) { return const Center(child: Text("暂无数据")); } else { return ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, index) { final crypto = snapshot.data![index]; return ListTile( title: Text(crypto.name), subtitle: Text("${crypto.symbol} - \$${crypto.priceUsd}"), ); }, ); } }, ), ); } }
五、调试技巧
- 在请求类中打印
response.body,确认接口返回的JSON结构是否符合预期 - 用Flutter DevTools的Network标签,查看请求状态码与响应内容
- 在FutureBuilder的错误分支显示具体错误,不要仅保留加载状态
内容的提问来源于stack exchange,提问作者mauricio
相关产品推荐
相关产品推荐

