Flutter中如何在Text Widget使用Shared Preferences存储的数据
错误原因
你在_fetchData里定义的pname、pdesc、pdue是函数内部的局部变量,组件的build方法无法访问这些变量;而且没有把读取到的数据存在组件的状态中,导致UI无法响应数据变化。
修复步骤
- 在State类中定义状态变量
在_ProjectTaskState类里声明用于存储SharedPreferences数据的变量,使用可空类型避免初始值问题:
class _ProjectTaskState extends State<ProjectTask> { // 定义状态变量,存储从SharedPreferences读取的数据 String? pname; String? pdesc; String? pdue; @override void initState() { super.initState(); _fetchData(); } // ... 其他代码 }
- 修改_fetchData函数,更新状态
读取SharedPreferences数据后,通过setState更新状态变量,触发UI重建:
Future<void> _fetchData() async { // 此处无需WidgetsFlutterBinding.ensureInitialized(),initState执行时Flutter环境已完成初始化 SharedPreferences localStorage = await SharedPreferences.getInstance(); setState(() { pname = localStorage.getString('project_name'); pdesc = localStorage.getString('project_desc'); pdue = localStorage.getString('project_due'); }); }
- 在Text Widget中安全使用变量
SharedPreferences可能读取不到数据(如首次打开或数据被清除),需用空值合并运算符??设置默认文本,避免null错误:
// 示例:项目名称展示 RichText( text: TextSpan(children: [ TextSpan( text: '项目名称: ', style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: Colors.black)), TextSpan( text: '${pname ?? '暂无项目名称'}', style: TextStyle(fontSize: 14, color: Colors.black)) ]), ),
同理,截止日期用${pdue ?? '暂无截止日期'},描述用${pdesc ?? '暂无项目描述'}即可。
修改后的完整代码
import 'package:flutter/material.dart'; import 'package:mne/Actual%20Tasks/activity_widget.dart'; import 'package:mne/UserTasks/task_widget.dart'; import 'package:shared_preferences/shared_preferences.dart'; class ProjectTask extends StatefulWidget { const ProjectTask({Key key}) : super(key: key); @override State<ProjectTask> createState() => _ProjectTaskState(); } class _ProjectTaskState extends State<ProjectTask> { String? pname; String? pdesc; String? pdue; @override void initState() { super.initState(); _fetchData(); } Future<void> _fetchData() async { SharedPreferences localStorage = await SharedPreferences.getInstance(); setState(() { pname = localStorage.getString('project_name'); pdesc = localStorage.getString('project_desc'); pdue = localStorage.getString('project_due'); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( automaticallyImplyLeading: true, centerTitle: true, title: const Text('Project Details')), body: SingleChildScrollView( child: Column(children: [ Container( child: Image.asset('assets/images/projectbanner.png'), ), // 项目名称展示 Container( child: Row(children: [ Container( padding: const EdgeInsets.only(right: 10, top: 8), child: const Icon(Icons.calendar_month_outlined)), RichText( text: TextSpan(children: [ TextSpan( text: '项目名称: ', style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: Colors.black)), TextSpan( text: '${pname ?? '暂无项目名称'}', style: TextStyle(fontSize: 14, color: Colors.black)) ])), ])), // 截止日期展示(修正原代码逻辑错误:原用pname展示截止日期) Container( padding: const EdgeInsets.only(top: 8), child: Row(children: [ Container( padding: const EdgeInsets.only(right: 10), child: const Icon(Icons.date_range_outlined)), RichText( text: TextSpan(children: [ TextSpan( text: '截止日期: ', style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: Colors.black)), TextSpan( text: '${pdue ?? '暂无截止日期'}', style: TextStyle(fontSize: 14, color: Colors.black)) ])), ])), // 描述标题 Container( padding: const EdgeInsets.only(top: 16, bottom: 8), child: const Text('Description', style: TextStyle(fontWeight: FontWeight.bold))), // 实际描述 Container( padding: const EdgeInsets.symmetric(horizontal: 16), child: Text(pdesc ?? '暂无项目描述')), // 任务标题 Container( padding: const EdgeInsets.only(top: 16, bottom: 8), child: const Text('Tasks', style: TextStyle(fontWeight: FontWeight.bold))), // 任务组件 Container(height: 630, child: const ActivityWidget()), ]), ), ); } }
注:原代码中存在逻辑错误——在截止日期区域误用了pname变量,已在修改后的代码中修正为pdue。
内容的提问来源于stack exchange,提问作者clio
相关产品推荐
相关产品推荐

