Flutter 零基础入门(三十八):网络请求实战 http / dio ------ 获取列表与刷新 UI
到目前为止,你已经掌握了:
- 动态页面(StatefulWidget + setState)
- 异步操作(Future / async / await)
- 用户交互反馈(SnackBar / AlertDialog)
接下来,我们进入 真正的业务数据交互阶段:
- 获取远程数据(列表、详情)
- 显示在 UI 上
- 刷新列表
Flutter 提供了多种网络请求方式,最常用的是 http 和 dio。
一、添加依赖
1️⃣ http
在 pubspec.yaml 添加:
yaml
dependencies:
http: ^1.1.0
2️⃣ dio(可选进阶)
dependencies:
dio: ^5.0.0
📌 这里我们先用 http 做基础示例。
二、简单 GET 请求示例(http)
import 'package:http/http.dart' as http;
import 'dart:convert';
Future<List<dynamic>> fetchPosts() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
if (response.statusCode == 200) {
return json.decode(response.body);
} else {
throw Exception('加载失败');
}
}
📌 json.decode 将 JSON 字符串转换为 Dart List / Map
三、结合 StatefulWidget 显示列表
class NetworkListPage extends StatefulWidget {
@override
_NetworkListPageState createState() => _NetworkListPageState();
}
class _NetworkListPageState extends State<NetworkListPage> {
List<dynamic> _posts = [];
bool _isLoading = true;
@override
void initState() {
super.initState();
loadData();
}
Future<void> loadData() async {
try {
final posts = await fetchPosts();
setState(() {
_posts = posts;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('加载失败: $e')),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('网络列表')),
body: _isLoading
? Center(child: CircularProgressIndicator())
: RefreshIndicator(
onRefresh: loadData,
child: ListView.builder(
itemCount: _posts.length,
itemBuilder: (context, index) {
final post = _posts[index];
return ListTile(
title: Text(post['title']),
subtitle: Text(post['body']),
);
},
),
),
);
}
}
📌 功能解析:
- initState → 页面初始化加载数据
- CircularProgressIndicator → 加载中提示
- RefreshIndicator → 下拉刷新
- setState → 更新 UI
四、网络请求常见坑
❌ 忘记 await → 页面先渲染空列表
❌ 异步未 try/catch → 崩溃
❌ build 里直接 await → 页面卡死
❌ 刷新列表忘记 setState → UI 不更新
📌 建议:
- 网络请求写在事件或 initState 中
- 异步操作完成后通过 setState 刷新 UI
- 异常必须捕获并提示用户
五、进阶:使用 dio
import 'package:dio/dio.dart';
final dio = Dio();
Future<List<dynamic>> fetchPostsDio() async {
final response = await dio.get('https://jsonplaceholder.typicode.com/posts');
return response.data;
}
📌 dio 功能更丰富:拦截器、请求取消、下载进度、FormData 上传
六、列表刷新与异步结合
使用 RefreshIndicator 包裹 ListView:
RefreshIndicator(
onRefresh: loadData,
child: ListView.builder(
itemCount: _posts.length,
itemBuilder: (context, index) {
final post = _posts[index];
return ListTile(title: Text(post['title']));
},
),
)
📌 下拉即可刷新网络数据 → 真实 App 必备功能
七、本篇你真正掌握了什么?
你已经学会:
- Flutter http 请求基本用法
- 异步获取网络数据
- 列表展示远程数据
- 下拉刷新与错误处理
- dio 进阶网络请求能力
📌 到这里为止:
你已经可以写出一个"数据动态加载的列表页面" ✅
八、一句话总结
Future / async / await 获取数据
setState 刷新 UI
RefreshIndicator + ListView 展示内容
🔜 下一篇预告
《Flutter 零基础入门(三十九):Pull-to-Refresh 与列表分页 ------ 完整列表交互实战》
下一篇我们将学习:
- 下拉刷新
- 上拉加载更多(分页)
- 列表分页结合网络请求
- 更完整的列表交互体验
🚀 实现真实业务列表的完整交互