You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何在Text Widget使用Shared Preferences存储的数据

解决Flutter中SharedPreferences数据在Text Widget展示的问题

错误原因

你在_fetchData里定义的pname、pdesc、pdue是函数内部的局部变量,组件的build方法无法访问这些变量;而且没有把读取到的数据存在组件的状态中,导致UI无法响应数据变化。

修复步骤

  1. 在State类中定义状态变量
    在_ProjectTaskState类里声明用于存储SharedPreferences数据的变量,使用可空类型避免初始值问题:
class _ProjectTaskState extends State<ProjectTask> {
  // 定义状态变量,存储从SharedPreferences读取的数据
  String? pname;
  String? pdesc;
  String? pdue;

  @override
  void initState() {
    super.initState();
    _fetchData();
  }
  // ... 其他代码
}
  1. 修改_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');
  });
}
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 09:46:39