Flutter跨类传递TextField参数失败及JSON解析类型不匹配问题
Flutter输入框值传递与JSON解析错误问题
我创建了用于API请求的RemoteService类,尝试将MyCustomFormState中TextInput的文本值传递过去,但编译后无法获取输入框的值,同时出现JSON解析异常。
相关代码
RemoteService类
class RemoteService { Future<List<Member>?> getUser({String? textForm}) async { var clientuser = http.Client(); var uriuser = Uri.parse('HTTP://MY URI//$textForm'); var responseuse = await clientuser.get(uriuser); if (responseuse.statusCode == 200) { var json = responseuse.body; return memberFromJson(json); } return null; // 补充无返回值路径的默认返回 } }
MyCustomFormState类
class MyCustomFormState extends State<MyCustomForm> { List<Member>? user1; var isLoaded = false; TextEditingController textFieldValue = TextEditingController(); @override void initState() { super.initState(); // 移除此处的getUse调用,避免初始化时请求空参数API // getUse(); } getUse() async { user1 = await RemoteService().getUser(textForm: textFieldValue.text); if (user1 != null) { setState(() { isLoaded = true; }); } } @override Widget build(BuildContext context) { return Column( children: [ Container( width: 200, child: TextFormField( controller: textFieldValue, decoration: InputDecoration( border: OutlineInputBorder(), fillColor: Color.fromARGB(255, 255, 255, 255), hintText: 'PLEASE ENTER ID', ), // 无需额外onChanged回调,直接通过controller获取最新值 ), ), Container( width: 120, height: 50, margin: EdgeInsets.only(top: 15), child: ElevatedButton( child: Text("LOGIN",style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold),), style: ElevatedButton.styleFrom( primary: Color.fromARGB(255, 45, 160, 253), elevation: 0, ), onPressed: () async { print("INPUT = ${textFieldValue.text}"); await getUse(); // 点击按钮时才调用API获取数据 print("Fetch API = ${user1?[0].name}"); }, ), ), ], ); } }
错误信息
Performing hot restart... Restarted application in 2,712ms. E/flutter (13579): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type '(dynamic) => Member' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>' of 'transform' E/flutter (13579): #0 memberFromJson (package:flutter_exit_interview/dtbmember.dart:8:79) E/flutter (13579): #1 RemoteService.getUser (package:flutter_exit_interview/main.dart:1061:14) E/flutter (13579): <asynchronous suspension> E/flutter (13579): #2 MyCustomFormState.getUse (package:flutter_exit_interview/main.dart:83:13) E/flutter (13579): <asynchronous suspension> E/flutter (13579):
Member Model类
// To parse this JSON data, do // // final member = memberFromJson(jsonString); import 'package:meta/meta.dart'; import 'dart:convert'; List<Member> memberFromJson(String str) => List<Member>.from(json.decode(str).map((x) => Member.fromJson(x))); String memberToJson(List<Member> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson()))); class Member { Member({ required this.status, required this.personId, required this.code, required this.name, required this.nickname, required this.deptcode, }); String status; String personId; String code; String name; String nickname; String deptcode; factory Member.fromJson(Map<String, dynamic> json) => Member( status: json["status"], personId: json["person_id"], code: json["code"], name: json["name"], nickname: json["nickname"], deptcode: json["deptcode"], ); Map<String, dynamic> toJson() => { "status": status, "person_id": personId, "code": code, "name": name, "nickname": nickname, "deptcode": deptcode, }; }
问题分析与解决方案
1. JSON解析错误原因
错误提示type '(dynamic) => Member' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>',说明API返回的JSON结构和Model解析逻辑不匹配:
- 当前
memberFromJson假设返回的是数组格式,但实际API可能返回单个对象,或嵌套了数组的复合对象(比如{"data": [...], "code": 200})。
对应解决方式:
如果API返回单个Member对象:
修改memberFromJson方法:Member memberFromJson(String str) => Member.fromJson(json.decode(str));同时调整RemoteService的返回类型:
Future<Member?> getUser({String? textForm}) async { // 其他代码不变 return memberFromJson(json); }并在MyCustomFormState中修改
user1类型为Member? user1;,打印语句改为print("Fetch API = ${user1?.name}");如果API返回嵌套数组的复合对象:
修改memberFromJson方法,指定解析数组的路径:List<Member> memberFromJson(String str) => List<Member>.from(json.decode(str)["data"].map((x) => Member.fromJson(x)));
2. 输入框值传递问题
原代码在initState中调用getUse(),此时输入框为空,导致请求空参数API;点击按钮时未重新触发API请求,所以user1始终是初始空值。
对应解决方式:
- 移除
initState中的getUse()调用; - 在登录按钮的
onPressed中异步调用getUse(),确保使用输入框的最新值请求API; - 直接通过
textFieldValue.text获取输入值,无需额外维护getusevalue变量和onChanged回调。
内容的提问来源于stack exchange,提问作者Rasale Migle
相关产品推荐
相关产品推荐

