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

Flutter使用flutter_svg渲染SVG字符串报错:Future不是Widget

Fixing "type 'Future' is not a subtype of type 'Widget'" with flutter_svg

Hey there, let's break down what's going wrong and fix this issue quickly:

The Root Cause

Your displaySVG() method is marked as async, which means it returns a Future<void> instead of a Widget. When you try to put this directly into the Container's child, Flutter throws that type mismatch error because it expects a Widget, not a Future.

On top of that, your manual Canvas drawing approach has a couple of issues (like an uninitialized PictureRecorder and no step to convert the picture into a renderable Image widget), so we can simplify this a lot using flutter_svg's built-in tools.

Solution 1: Use SvgPicture.string() (Simplest Approach)

flutter_svg provides a ready-to-use widget that renders SVG directly from a string—no need to handle DrawableRoot or Picture manually. Here's the corrected code:

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class KanjiGradeGenerator extends StatefulWidget {
  @override
  _KanjiGradeState createState() => _KanjiGradeState();
}

class _KanjiGradeState extends State<KanjiGradeGenerator> {
  final String rawSvg = '''<?xml version="1.0" encoding="UTF-8"?>
    <svg xmlns="http://www.w3.org/2000/svg" width="109" height="109" viewBox="0 0 109 109">
      <g id="kvg:StrokePaths_080a1" style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;">
        <path id="kvg:080a1-s1" d="M20.22,18.74c0.77,0.77,0.79,2.14,0.8,3.05C21.38,62,20.62,75,11.5,89.39"/>
      </g>
    </svg>''';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        // Use SvgPicture.string directly to render your SVG string
        child: SvgPicture.string(
          rawSvg,
          width: 200, // Adjust size as needed
          height: 200,
          fit: BoxFit.contain,
        ),
      ),
    );
  }
}

Solution 2: If You Need Async Processing (Using FutureBuilder)

If you ever need to load the SVG string asynchronously (e.g., from a network call or local file), you can use FutureBuilder to handle the async operation and render the Widget once it's ready:

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class KanjiGradeGenerator extends StatefulWidget {
  @override
  _KanjiGradeState createState() => _KanjiGradeState();
}

class _KanjiGradeState extends State<KanjiGradeGenerator> {
  // Simulate an async SVG load (replace with your actual logic)
  Future<String> _loadSvgString() async {
    await Future.delayed(const Duration(milliseconds: 500));
    return '''<?xml version="1.0" encoding="UTF-8"?>
    <svg xmlns="http://www.w3.org/2000/svg" width="109" height="109" viewBox="0 0 109 109">
      <g id="kvg:StrokePaths_080a1" style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;">
        <path id="kvg:080a1-s1" d="M20.22,18.74c0.77,0.77,0.79,2.14,0.8,3.05C21.38,62,20.62,75,11.5,89.39"/>
      </g>
    </svg>''';
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder<String>(
        future: _loadSvgString(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            // Render SVG once data is available
            return Container(
              child: SvgPicture.string(
                snapshot.data!,
                width: 200,
                height: 200,
                fit: BoxFit.contain,
              ),
            );
          } else if (snapshot.hasError) {
            // Show error message if something goes wrong
            return Center(child: Text('Error loading SVG: ${snapshot.error}'));
          } else {
            // Show loading indicator while waiting
            return const Center(child: CircularProgressIndicator());
          }
        },
      ),
    );
  }
}

Key Takeaways

  • Never return an async function directly as a Widget—use FutureBuilder for async operations that produce Widgets.
  • flutter_svg has built-in widgets like SvgPicture.string(), SvgPicture.asset(), and SvgPicture.network() that handle all low-level rendering for you, so you don't need to mess with Picture or Canvas manually unless you have a specific custom use case.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:36:00