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));
额外优化建议
- 指定FutureBuilder泛型:避免类型不确定的警告,让代码更严谨:
FutureBuilder<List<User>>( future: getUserData(), builder: (context, AsyncSnapshot<List<User>> snapShot){ // ... 后续逻辑 }, )
- 避免build方法重复调用异步请求:每次build都会重新调用
getUserData(),建议在initState中初始化future:
late Future<List<User>> _userFuture; @override void initState() { super.initState(); _userFuture = getUserData(); } // 然后在FutureBuilder中使用: future: _userFuture,
- 正确判断加载状态:除了判断
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
相关产品推荐
相关产品推荐

