Flutter:如何在另一个类的Text Widget中展示API响应数据?
解决Flutter中API数据在Text Widget的展示问题
我已经通过GET方法成功获取了API数据,现在需要了解如何在另一个类的Text Widget中展示这些响应内容。以下是我使用的相关代码:
API调用类
const apiHost = 'andruxnet-random-famous-quotes.p.rapidapi.com'; const apiUrl = 'https://andruxnet-random-famous-quotes.p.rapidapi.com/'; const apiKey = '14b77a3e77msh224667c7b07c6edp170846jsn2144e4d9735f'; class Quote { static Future getQuote() async { var client = http.Client(); var uri = Uri.parse(apiUrl); var response = await client.get( uri, headers: {'X-RapidAPI-Key': apiKey, 'X-RapidAPI-Host': apiHost}, ); if(response.statusCode == 200){ var json = response.body; return getQuoteFromJson(json); } else { throw Exception(response.reasonPhrase); } } }
数据模型类
import 'dart:convert'; List<GetQuote> getQuoteFromJson(String str) => List<GetQuote>.from(json.decode(str).map((x) => GetQuote.fromJson(x))); String getQuoteToJson(List<GetQuote> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson()))); class GetQuote { GetQuote({ required this.quoteText, required this.author, }); String quoteText; String author; factory GetQuote.fromJson(Map<String, dynamic> e) => GetQuote( quoteText: e["quote"], author: e["author"], ); Map<String, dynamic> toJson() => { "quote": quoteText, "author": author, }; }
UI代码
class QuotePage extends StatefulWidget { const QuotePage({super.key}); @override State<QuotePage> createState() => _QuotePageState(); } class _QuotePageState extends State<QuotePage> { List<GetQuote> quote = []; @override void initState() { super.initState(); getData(); } getData() async{ final response = await Quote.getQuote(); setState(() { quote = response; }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor, appBar: AppBar( elevation: 0.0, backgroundColor: backgroundColor, centerTitle: true, title: const Text( 'Quote App', style: kAppBarTextStyle, ), ), body: Stack( alignment: Alignment.center, children: [ PositionedWidget( top: 50, width: 250.0, height: 500, child: Container( decoration: BoxDecoration( color: smallContainerColor, borderRadius: BorderRadius.circular(10.0), ), ), ), PositionedWidget( top: 60, width: 300.0, height: 500, child: Container( decoration: BoxDecoration( color: mediumContainerColor, borderRadius: BorderRadius.circular(10.0), ), ), ), PositionedWidget( top: 70, width: 350.0, height: 500, child: ClipRRect( borderRadius: BorderRadius.circular(10.0), child: Container( decoration: const BoxDecoration( image: DecorationImage( fit: BoxFit.cover, image: AssetImage(kContainerImage), ), ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children:const [ TextContainer( text: ('Hello'), style: kQuoteTextStyle, padding: kQuotePadding, ), Align( alignment: Alignment.bottomRight, child: TextContainer( text: 'Author\'s name', style: kAuthornameTextStyle, padding: kAuthornamePadding, ), ) ], ), ), ), ), ], ), floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, floatingActionButton: FloatingActionButton.extended( backgroundColor: kFloatingActionButtonColor, onPressed: getData, label: const Text( 'Next Quote', style: kFloatingActionTextStle, ), ), ); } }
解决方案
1. 完善API类的类型声明
给getQuote()指定明确返回类型,避免类型歧义:
class Quote { static Future<List<GetQuote>> getQuote() async { var client = http.Client(); var uri = Uri.parse(apiUrl); var response = await client.get( uri, headers: {'X-RapidAPI-Key': apiKey, 'X-RapidAPI-Host': apiHost}, ); if(response.statusCode == 200){ var json = response.body; return getQuoteFromJson(json); } else { throw Exception(response.reasonPhrase); } } }
2. 修改UI代码动态展示数据
移除children前的const(因为内容是动态的),根据quote列表的状态展示数据:
@override Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor, appBar: AppBar( elevation: 0.0, backgroundColor: backgroundColor, centerTitle: true, title: const Text( 'Quote App', style: kAppBarTextStyle, ), ), body: Stack( alignment: Alignment.center, children: [ // 保留原有定位容器代码 PositionedWidget( top: 70, width: 350.0, height: 500, child: ClipRRect( borderRadius: BorderRadius.circular(10.0), child: Container( decoration: const BoxDecoration( image: DecorationImage( fit: BoxFit.cover, image: AssetImage(kContainerImage), ), ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ TextContainer( text: quote.isNotEmpty ? quote[0].quoteText : "加载中...", style: kQuoteTextStyle, padding: kQuotePadding, ), Align( alignment: Alignment.bottomRight, child: TextContainer( text: quote.isNotEmpty ? quote[0].author : "加载中...", style: kAuthornameTextStyle, padding: kAuthornamePadding, ), ) ], ), ), ), ), ], ), // 保留原有悬浮按钮代码 ); }
3. 优化数据获取的类型安全
给getData()中的response指定类型,消除类型警告:
getData() async{ final List<GetQuote> response = await Quote.getQuote(); setState(() { quote = response; }); }
4. 可选:添加错误处理
在getData()中加入异常捕获,处理API请求失败的情况:
getData() async{ try{ final List<GetQuote> response = await Quote.getQuote(); setState(() { quote = response; }); } catch(e){ if(mounted){ ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("获取语录失败:$e")) ); } } }
内容的提问来源于stack exchange,提问作者Martins
相关产品推荐
相关产品推荐

