Flutter设置Profile组件值报错:Future无法赋值给String类型
Flutter渲染用户Profile时Future转String报错解决方案
我是一名JavaScript开发者,目前为公司需求做Flutter开发,在把用户Profile值渲染到GUI时碰到问题。报错信息:The argument type 'Future' can't be assigned to the parameter type 'String'
问题代码
profile.dart
import 'package:flutter/material.dart'; import 'package:profile/profile.dart'; import 'package:cs_app/models/user.dart'; import 'package:cs_app/models/cs_data.dart'; import 'package:cs_app/models/profile_data.dart'; import 'package:provider/provider.dart'; class AdminPage extends StatefulWidget { const AdminPage({Key? key}) : super(key: key); @override State<AdminPage> createState() => _AdminPageState(); } profile_value(key) async { var value = await profileData.user_profile(key); print("rtn: " + value); // rtn: admin, can get the print value return value; } class _AdminPageState extends State<AdminPage> { @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Profile( imageUrl: "https://images.unsplash.com/photo-1598618356794-eb1720430eb4?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80", name: profile_value("username"), // run func, get rtn value, render website: profile_value("website"), designation: profile_value("designation"), email: "xxx@gmail.com", phone_number: "12345456", ), )); } }
profile_data.dart
import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:cs_app/views/login.dart'; import 'dart:convert'; import 'package:cs_app/models/sharedPref.dart'; class profileData { static user_profile(key) async { var value = await SharedPref().read("user"); var decode_value = json.decode(value); var key_decode_value = decode_value[key]; print("key: " + key); print("value: " + key_decode_value); // key: username // value: admin return key_decode_value; } }
解决方案
问题根源
profile_value是异步函数,返回的是Future<String>类型,但Profile组件的name、website等参数需要直接传入String,不能直接把Future丢进去。下面给两种实用的处理方式:
方式一:提前预加载数据(推荐)
在组件初始化时加载数据,存到State变量里,再渲染UI:
class _AdminPageState extends State<AdminPage> { String? _username; String? _website; String? _designation; @override void initState() { super.initState(); // 页面初始化时加载数据 _loadProfileData(); } Future<void> _loadProfileData() async { // 批量获取数据 _username = await profile_value("username"); _website = await profile_value("website"); _designation = await profile_value("designation"); // 通知Flutter更新UI setState(() {}); } @override Widget build(BuildContext context) { return Scaffold( body: Center( // 数据未加载完时显示加载动画 child: _username == null ? CircularProgressIndicator() : Profile( imageUrl: "https://images.unsplash.com/photo-1598618356794-eb1720430eb4?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80", name: _username!, website: _website!, designation: _designation!, email: "xxx@gmail.com", phone_number: "12345456", ), )); } }
方式二:用FutureBuilder直接处理异步
适合不需要缓存数据的场景,直接在build方法里处理异步逻辑:
@override Widget build(BuildContext context) { return Scaffold( body: Center( child: FutureBuilder<Map<String, String>>( future: _getAllProfileValues(), builder: (context, snapshot) { // 加载中 if (snapshot.connectionState == ConnectionState.waiting) { return CircularProgressIndicator(); } // 加载出错 else if (snapshot.hasError) { return Text("加载失败,请重试"); } // 加载完成渲染UI else { final profileData = snapshot.data!; return Profile( imageUrl: "https://images.unsplash.com/photo-1598618356794-eb1720430eb4?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80", name: profileData["username"]!, website: profileData["website"]!, designation: profileData["designation"]!, email: "xxx@gmail.com", phone_number: "12345456", ); } }, ), )); } // 封装批量获取方法 Future<Map<String, String>> _getAllProfileValues() async { return { "username": await profile_value("username"), "website": await profile_value("website"), "designation": await profile_value("designation"), }; }
额外优化:减少SharedPref重复读取
现在每次调用user_profile都会重新读取SharedPref的user数据,可以改成一次性读取后复用,提升性能:
class profileData { // 封装一次性获取完整用户信息的方法 static Future<Map<String, dynamic>> _getUserProfile() async { var value = await SharedPref().read("user"); return json.decode(value); } static Future<String> user_profile(String key) async { var userData = await _getUserProfile(); return userData[key] as String; } // 新增批量获取字段的方法 static Future<Map<String, String>> getAllProfileFields(List<String> keys) async { var userData = await _getUserProfile(); return { for (var key in keys) key: userData[key] as String, }; } }
内容的提问来源于stack exchange,提问作者chin
相关产品推荐
相关产品推荐

