无法将Firestore中的username数据显示到TextFormField组件中
问题:Firestore数据无法在TextFormFieldWidget的hint中显示
我从Firestore读取名为username的数据,截图左上角的“asd”是成功获取到的示例数据——通过ListTile的title调用GetUsername组件能正常展示。但把GetUsername组件放到自定义TextFormFieldWidget的hint属性里时,数据就显示不出来了。
相关代码
ListTile( title: GetUsername(documentId: docIDs[index]), trailing: GetGender(documentId: docIDs[index])), TextFormFieldWidget( action: TextInputAction.next, controller: controller, hint: '${GetUsername(documentId: docIDs[index])}', icon: Icons.abc, obs: false, read: true, )

GetUsername组件实现代码
final String documentId; const GetUsername({super.key, required this.documentId}); @override Widget build(BuildContext context) { CollectionReference users = FirebaseFirestore.instance.collection('profiles'); return FutureBuilder<DocumentSnapshot>( future: users.doc(documentId).get(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { Map<String, dynamic> data = snapshot.data!.data() as Map<String, dynamic>; return Text('${data['username']}'); } return Text('Loading'); }, ); }
问题原因
GetUsername是一个Widget组件,直接用'${GetUsername(...)}'会把Widget转换成字符串(默认输出类似Instance of 'GetUsername'),而不是渲染它内部的文本内容,所以hint里看不到实际的username。
两种解决方法
方法一:抽离数据获取逻辑,用FutureBuilder统一处理
把获取username的逻辑单独做成异步方法,不要封装成Widget,这样就能拿到字符串值传给hint:
// 单独写获取username的异步方法 Future<String> getUsername(String documentId) async { CollectionReference users = FirebaseFirestore.instance.collection('profiles'); DocumentSnapshot snapshot = await users.doc(documentId).get(); if (snapshot.exists) { Map<String, dynamic> data = snapshot.data() as Map<String, dynamic>; return data['username'] ?? 'Unknown'; } return 'Unknown'; }
然后在页面中用FutureBuilder包裹组件,把获取到的username传给对应的位置:
FutureBuilder<String>( future: getUsername(docIDs[index]), builder: (context, snapshot) { String username = snapshot.data ?? 'Loading'; return Column( children: [ ListTile( title: Text(username), trailing: GetGender(documentId: docIDs[index]), ), TextFormFieldWidget( action: TextInputAction.next, controller: controller, hint: username, icon: Icons.abc, obs: false, read: true, ), ], ); }, )
方法二:修改自定义组件,支持传入Widget作为hint
如果你的TextFormFieldWidget是自己写的,直接把hint的参数类型改成Widget?,这样就能直接传入GetUsername组件:
// 修改TextFormFieldWidget的参数定义 class TextFormFieldWidget extends StatelessWidget { final TextInputAction? action; final TextEditingController? controller; final Widget? hint; // 把String改成Widget类型 final IconData icon; final bool obs; final bool read; const TextFormFieldWidget({ super.key, this.action, this.controller, this.hint, required this.icon, required this.obs, required this.read, }); @override Widget build(BuildContext context) { return TextFormField( controller: controller, textInputAction: action, obscureText: obs, readOnly: read, decoration: InputDecoration( prefixIcon: Icon(icon), // 使用hintWidget代替原来的hintText hintWidget: hint ?? const Text(''), ), ); } }
之后直接传入GetUsername组件即可:
TextFormFieldWidget( action: TextInputAction.next, controller: controller, hint: GetUsername(documentId: docIDs[index]), icon: Icons.abc, obs: false, read: true, )
内容的提问来源于stack exchange,提问作者KKot
相关产品推荐
相关产品推荐

