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

使用Flutter Screenshot包捕获LinearPercentIndicator时遇width空指针错误

问题解决:Screenshot捕获LinearPercentIndicator时触发NoSuchMethodError

我在用Screenshot包捕获LinearPercentIndicator组件图像时,反复遇到以下错误:

NoSuchMethodError: The getter 'width' was called on null.
Receiver: null
Tried calling: width

相关函数代码如下:

Future<String> progressBarPath(double progress) async {
  final progressFile = File('${(await getTemporaryDirectory()).path}/image.png');
  var indicator = LinearPercentIndicator(
    percent: progress > 1.0 ? 1.0 : progress,
    width: 100,
    lineHeight: 13,
    animation: true,
    animationDuration: 1000,
    progressColor: FlutterFlowTheme.primaryColor,
    backgroundColor: Color(0xFFF1F4F8),
    center: Text(
      formatNumber(
          progress > 1.0 ? 1.0 : progress,
          formatType: FormatType.percent),
      style: FlutterFlowTheme.bodyText1.override(
        fontFamily: 'Lato',
        color: Colors.black,
        fontSize: 12,
        fontWeight: FontWeight.bold,
      ),
    ),
    barRadius: Radius.circular(20),
  );

// 图像转换逻辑
  screenshotController.captureFromWidget(
    InheritedTheme.captureAll(context, Material(child: indicator)),
        delay: Duration(seconds: 1),
  ).then((capturedProgress) async {
    await progressFile.create(recursive: true);
    await progressFile.writeAsBytes(capturedProgress);
  });
  print(progressFile.path);
  return progressFile.path;
}

可能原因及修复方案

1. 上下文未提供完整布局环境

InheritedTheme.captureAll依赖的context可能缺少完整的Material布局约束,导致LinearPercentIndicator内部无法正确计算宽度。可以用MaterialApp + Scaffold包裹组件,确保布局环境完整:

screenshotController.captureFromWidget(
  MaterialApp(
    home: Scaffold(body: Center(child: indicator)),
  ),
  delay: Duration(seconds: 1),
)

2. 组件缺少明确尺寸约束

即使给LinearPercentIndicator指定了width参数,如果父布局没有明确约束,内部计算时仍可能出现width为null的情况。用SizedBox强制包裹,固定尺寸:

var indicator = SizedBox(
  width: 100,
  child: LinearPercentIndicator(
    percent: progress > 1.0 ? 1.0 : progress,
    lineHeight: 13,
    // 此处可移除width参数,由SizedBox控制宽度
    animation: true,
    animationDuration: 1000,
    progressColor: FlutterFlowTheme.primaryColor,
    backgroundColor: Color(0xFFF1F4F8),
    center: Text(...),
    barRadius: Radius.circular(20),
  ),
);

3. 异步逻辑顺序错误

原代码中直接返回文件路径,但captureFromWidget是异步操作,可能文件还未写入就返回了路径。改用await等待捕获完成,确保文件写入后再返回:

Future<String> progressBarPath(double progress) async {
  final progressFile = File('${(await getTemporaryDirectory()).path}/image.png');
  var indicator = SizedBox(
    width: 100,
    child: LinearPercentIndicator(...),
  );

  // 等待捕获完成
  final capturedProgress = await screenshotController.captureFromWidget(
    MaterialApp(home: Scaffold(body: Center(child: indicator))),
    delay: Duration(seconds: 1),
  );
  
  await progressFile.create(recursive: true);
  await progressFile.writeAsBytes(capturedProgress);
  
  print(progressFile.path);
  return progressFile.path;
}

4. ScreenshotController未正确初始化

确保控制器在组件初始化时创建,避免提前销毁:

late ScreenshotController screenshotController;

@override
void initState() {
  super.initState();
  screenshotController = ScreenshotController();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:05:18