Flutter如何展示API返回的HTML数据?使用flutter_html遇Future实例显示问题
问题原因
getHtml()是异步方法,返回的是Future<String>类型,你没有等待异步执行完成就直接调用toString(),自然只会输出Future对象的描述文本。
方案1:使用FutureBuilder(更推荐)
这是Flutter处理异步数据渲染的标准写法,还可以自带加载、错误状态处理,无需额外定义变量存储HTML内容:
@override Widget build(BuildContext context) { return Scaffold( body: FutureBuilder<String>( future: getHtml(), builder: (context, snapshot) { // 加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 错误状态处理 if (snapshot.hasError) { return Center(child: Text('加载失败:${snapshot.error}')); } // 请求成功渲染HTML final htmlContent = snapshot.data ?? ''; return Center( child: Html(data: htmlContent), ); }, ), ); }
该方案可以直接删掉initState中关于变量i的赋值逻辑。
方案2:用setState更新状态
如果需要把HTML内容存在变量里后续复用,可以用这种写法:
- 先修改变量定义和初始化逻辑:
// 定义HTML内容变量,默认是空字符串 String htmlContent = ''; @override void initState() { super.initState(); loadHtml(); } // 单独封装加载方法 Future<void> loadHtml() async { final result = await getHtml(); // 请求完成后调用setState更新状态触发重绘 setState(() { htmlContent = result; }); }
- 直接在build中使用变量渲染:
@override Widget build(BuildContext context) { return Scaffold( body: Container( child: Center( child: Html( data: htmlContent, ), ), ), ); }
额外优化提醒
你当前的getHtml()方法里调用了两次response.stream.bytesToString(),stream只能被监听一次,第二次调用会拿不到数据,需要改成只调用一次缓存结果:
Future<String> getHtml() async { var headers = { 'Cookie': 'ci_session=hgiugh' }; var request = http.MultipartRequest('POST', Uri.parse('http://xxx/get')); request.fields.addAll({ '': '', }); request.headers.addAll(headers); final http.StreamedResponse response = await request.send(); // 只调用一次,缓存结果 final responseStr = await response.stream.bytesToString(); if (response.statusCode == 200) { print("HTML_RESULT$responseStr"); } else { print(response.reasonPhrase); } return responseStr; }
内容的提问来源于stack exchange,提问作者Mas'ud Al Hafiz
相关产品推荐
相关产品推荐

