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

Flutter项目报错:type 'String' is not a subtype of type 'Widget?'求解决

Flutter错误修复:type 'String' is not a subtype of type 'Widget?'

我是Flutter新手,开发了一个从API获取数据并在ListView中展示的项目,预期snapshot无数据时显示加载界面。修复小问题后运行程序,出现错误:type 'String' is not a subtype of type 'Widget?',以下是我的代码及控制台输出,请求协助解决。

我的代码:

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class DataFromAPI extends StatefulWidget {
  const DataFromAPI({Key? key}) : super(key: key);

  @override
  State<DataFromAPI> createState() => _DataFromAPIState();
}

class _DataFromAPIState extends State<DataFromAPI> {

  getUserData() async{
    var response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
    var jsonData = jsonDecode(response.body);
    print(response.body);
    List<User> users = [];

    for(var u in jsonData){
      User user = User(u['name'],u['email'],u['username']);
      users.add(user);
    }
    //print(users.length);
    return users;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Get Data From API'),
      ),
      body: Container(
        child: Card(
          child: FutureBuilder(
            future: getUserData(),
            builder: (context, AsyncSnapshot snapShot){
              if(snapShot.data == null){
                return Container(child: Center(child: Text('Loading'),),);
              }else{
                return ListView.builder(
                    itemCount: snapShot.data.length,
                    itemBuilder: (context, i){
                      return ListTile(title: snapShot.data[i].name);
                    });
              }
            },
          ),
    ))
    );
  }
}

class User{
  final String name, email, userName;
  User(this.name, this.email, this.userName);
}

控制台输出:

Syncing files to device sdk gphone64 x86 64...
Reloaded 0 libraries in 506ms (compile: 12 ms, reload: 0 ms, reassemble: 433 ms).
D/EGL_emulation( 6751): app_time_stats: avg=8895.54ms min=975.35ms max=16815.74ms count=2

======== Exception caught by widgets library =======================================================
The following _TypeError was thrown building:
type 'String' is not a subtype of type 'Widget?'

问题原因及修复

错误根源在于ListTile的title属性要求传入Widget类型,但你直接传入了字符串snapShot.data[i].name,类型不匹配导致报错。

修改itemBuilder部分的代码,把字符串包裹在Text组件内即可:

return ListTile(title: Text(snapShot.data[i].name));

额外优化建议

  1. 指定FutureBuilder泛型:避免类型不确定的警告,让代码更严谨:
FutureBuilder<List<User>>(
  future: getUserData(),
  builder: (context, AsyncSnapshot<List<User>> snapShot){
    // ... 后续逻辑
  },
)
  1. 避免build方法重复调用异步请求:每次build都会重新调用getUserData(),建议在initState中初始化future:
late Future<List<User>> _userFuture;

@override
void initState() {
  super.initState();
  _userFuture = getUserData();
}

// 然后在FutureBuilder中使用:
future: _userFuture,
  1. 正确判断加载状态:除了判断snapShot.data == null,还可以通过connectionState更精准处理加载、错误等状态:
builder: (context, AsyncSnapshot<List<User>> snapShot){
  if(snapShot.connectionState == ConnectionState.waiting){
    return const Center(child: Text('Loading'));
  } else if(snapShot.hasError){
    return Center(child: Text('Error: ${snapShot.error}'));
  } else if(!snapShot.hasData || snapShot.data!.isEmpty){
    return const Center(child: Text('No data found'));
  } else {
    return ListView.builder(
      itemCount: snapShot.data!.length,
      itemBuilder: (context, i){
        return ListTile(title: Text(snapShot.data![i].name));
      },
    );
  }
}

内容的提问来源于stack exchange,提问作者Dimuth De Zoysa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 19:55:36