You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pdf、dio、printing包加载URL PDF时遇三类类型错误求助

解决Dio+Printing包读取PDF的类型匹配错误

错误原因及修复方案

1. 参数类型 Future<Uint8List?> 无法分配给参数类型 Future<Uint8List>?

FutureBuilder 声明的泛型是 Uint8List,但 _fetchPdfContent 返回的是可空的 Future<Uint8List?>,类型不匹配。将 FutureBuilder 的泛型改为 Uint8List?,同时在判断快照数据时处理空值情况。

2. 返回类型 Uint8List? 不符合闭包上下文要求的 FutureOr<Uint8List>

PdfPreview 的 build 回调要求返回非空的 FutureOr<Uint8List>,但 snapshot.data 是可空类型。在确认 snapshot.hasData 后,使用断言确保数据非空,同时将回调改为返回 Future.value(snapshot.data!) 以符合异步返回要求。

3. 参数类型 List<int>? 无法分配给参数类型 List<int>

Dio 请求返回的 response.data 可能为 null,直接传入 Uint8List.fromList 会触发类型错误。添加空值判断,若 response.data 为空则抛出异常,避免类型不匹配。

修改后的完整代码

class _MyHomePageState extends State<MyHomePage> {
  String _url = 
      "https://www.au-sonpo.co.jp/corporate/upload/article/89/article_89_1.pdf";

  void _refresh() {
    setState(() {
      _url = 
      "https://www.au-sonpo.co.jp/corporate/upload/article/90/article_90_1.pdf";
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: FutureBuilder<Uint8List?>( // 泛型改为可空类型
        future: _fetchPdfContent(_url),
        builder: (context, snapshot) {
          if (snapshot.hasData && snapshot.data != null) { // 额外判断数据非空
            return PdfPreview(
              allowPrinting: false,
              allowSharing: false,
              canChangePageFormat: false,
              initialPageFormat:
              PdfPageFormat(100 * PdfPageFormat.mm, 120 * PdfPageFormat.mm),
              build: (format) => Future.value(snapshot.data!), // 返回Future包裹的非空数据
            );
          } else if (snapshot.hasError) {
            return Center(child: Text('加载失败: ${snapshot.error}')); // 新增错误状态处理
          }
          return Center(
            child: CircularProgressIndicator(),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _refresh,
        tooltip: 'Refresh',
        child: Icon(Icons.refresh),
      ),
    );
  }

  Future<Uint8List?> _fetchPdfContent(final String url) async {
    try {
      final Response<List<int>> response = await Dio().get<List<int>>(
        url,
        options: Options(responseType: ResponseType.bytes),
      );
      if (response.data == null) { // 判断response.data是否为空
        throw Exception('PDF数据为空');
      }
      return Uint8List.fromList(response.data!); // 断言非空后转换
    } catch (e) {
      print(e);
      return null;
    }
  }
}

关键修改点说明

  • 调整 FutureBuilder 泛型为 Uint8List?,与 _fetchPdfContent 返回类型匹配。
  • 在 PdfPreview 的 build 回调中,用 Future.value() 包裹数据,通过断言确保数据非空(已提前判断)。
  • 在 _fetchPdfContent 中新增 response.data 空值校验,避免传入可空列表。
  • 增加错误状态UI展示,优化加载失败场景的用户体验。

内容的提问来源于stack exchange,提问作者learner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 15:55:17