第 12 章 实用插件速查与入门

以下均为 pub.dev 官方或社区验证的高口碑包(版本号以 pub.dev 最新稳定版为准)。每个给出最小可运行示例。

插件用途备注
riverpod状态管理本手册主推,见第 7.5 章
go_router声明式路由见第 6.3 章
dio网络请求拦截器/取消/下载,见下文
shared_preferences / sqflite持久化见第 9 章
cached_network_image网络图片+磁盘缓存见下文
intl格式化与多语言见第 11 章
flutter_dotenv环境变量(.env)区分测试/生产 API 地址
permission_handler运行时权限申请相机/定位/存储
image_picker拍照/选图官方维护
webview_flutter内嵌网页官方维护

12.1 dio:拦截器与统一错误处理

dependencies:
  dio: ^5.7.0
final dio = Dio(BaseOptions(
  baseUrl: 'https://api.example.com',
  connectTimeout: const Duration(seconds: 10),
  receiveTimeout: const Duration(seconds: 15),
));

// 拦截器:统一加 token、打日志
dio.interceptors.add(InterceptorsWrapper(
  onRequest: (options, handler) {
    options.headers['Authorization'] = 'Bearer <token>';
    handler.next(options);
  },
  onError: (e, handler) {
    if (e.response?.statusCode == 401) {/* 跳转登录页 */}
    handler.next(e);
  },
));

// 用法与 http 类似但返回已解析的对象
final resp = await dio.get('/user/1');
final user = resp.data; // Map

12.2 cached_network_image:带缓存的图片

CachedNetworkImage(
  imageUrl: 'https://picsum.photos/300/200',
  placeholder: (_, __) => const Center(child: CircularProgressIndicator()),
  errorWidget: (_, __, ___) => const Icon(Icons.broken_image),
  fit: BoxFit.cover,
)

12.3 image_picker + permission_handler:拍照上传

final picker = ImagePicker();
final XFile? photo = await picker.pickImage(source: ImageSource.camera, imageQuality: 80);
if (photo != null) {
  final file = File(photo.path); // 之后可 multipart 上传
}

// 动态权限(相机等敏感权限要先申请)
final status = await Permission.camera.request();
if (status.isGranted) {/* 已授权 */}
← 上一章第 11 章 主题与深色模式(完整可运行示例)下一章 →第 13 章 调试与测试
✉ 联系作者:linghurongjun@sina.com