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

Flutter中如何通过全局变量获取Future函数内的变量值

问题原因

你的代码拿不到值核心是两个问题:

  • StatelessWidget是不可变组件,内部声明的成员变量value1不属于可维护的可变状态,就算赋值也不会被组件持有感知,本质上你写在StatelessWidget里的可变成员变量每次组件重建都会重置成初始值。
  • savedata是Future异步方法,你在按钮点击事件里直接调用savedata(context)没有加await等待,调用后会立刻执行后续逻辑,这时候savedata内部的赋值代码还没跑完,你立刻读value1拿到的只能是初始的null。
  • 额外语法问题:你把@override注解错放在了inputtext声明上方,正确位置应该标在build方法上,另外不要导入flutter/src/路径下的内部文件,会有版本兼容风险。
解决方案

推荐方案:改用StatefulWidget维护状态(符合Flutter官方状态管理规范)

直接把组件改成StatefulWidget,可变状态放到State类中,调用异步方法时等待执行完成再做后续操作,修正后代码如下:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class LoginScreen extends StatefulWidget {
  const LoginScreen({Key? key}) : super(key: key);

  @override
  State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final TextEditingController inputtext = TextEditingController();
  String? value1;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: SizedBox(
            width: 300,
            child: Column(
              children: [
                TextField(
                  controller: inputtext,
                  decoration: const InputDecoration(
                    border: OutlineInputBorder(),
                    label: Text('Enter your name')
                  ),
                ),
                const SizedBox(height: 16),
                ElevatedButton.icon(
                  onPressed: () async {
                    // 等待异步存值、赋值逻辑全部执行完成
                    await savedata(context);
                    // 此时读取value1就是更新后的值
                    debugPrint('当前获取到的value1值:$value1');
                  },
                  icon: const Icon(Icons.arrow_right),
                  label: const Text('click Here')
                )
              ],
            ),
          ),
        ),
      ),
    );
  }

  Future<void> savedata(BuildContext context) async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    // 等待写入完成
    await prefs.setString('Name', inputtext.text.trim());
    final String? savedValue = prefs.getString('Name');

    debugPrint('存储的savedValue值:$savedValue');
    if (savedValue == 'jibi' && context.mounted) {
      Navigator.of(context).pushNamed('Screen_2');
    }
    // 赋值时通过setState触发界面更新,如果不需要更新界面也可直接赋值
    setState(() {
      value1 = savedValue;
    });
  }
}

关键修改点:

  • 替换StatelessWidget为StatefulWidget,将可变变量、控制器全部放到State类中管理,赋值后通过setState可以同步刷新所有用到value1的界面位置
  • 按钮点击回调改为异步,调用savedata时加await,等所有异步逻辑执行完毕再读取value1,解决时序问题
  • 路由跳转前增加context.mounted判断,避免异步操作完成后组件已经销毁导致的运行时报错
  • 移除了错误的src路径导入,修正了@override注解位置

备选方案:使用顶级全局变量(不推荐,易出现值污染、难维护)

如果你一定要用全局变量,需要把value1声明在类的外部作为顶级变量,同样需要等待异步方法执行完成再读取:

// 顶级全局变量,声明在所有类外部
String? globalValue1;

class LoginScreen extends StatelessWidget {
  LoginScreen({Key? key}) : super(key: key);

  final TextEditingController inputtext = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: SizedBox(
            width: 300,
            child: Column(
              children: [
                TextField(
                  controller: inputtext,
                  decoration: const InputDecoration(
                    border: OutlineInputBorder(),
                    label: Text('Enter your name')
                  ),
                ),
                const SizedBox(height: 16),
                ElevatedButton.icon(
                  onPressed: () async {
                    await savedata(context);
                    debugPrint('全局变量值:$globalValue1');
                  },
                  icon: const Icon(Icons.arrow_right),
                  label: const Text('click Here')
                )
              ],
            ),
          ),
        ),
      ),
    );
  }

  Future<void> savedata(BuildContext context) async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setString('Name', inputtext.text.trim());
    final String? savedValue = prefs.getString('Name');

    if (savedValue == 'jibi') {
      Navigator.of(context).pushNamed('Screen_2');
    }
    globalValue1 = savedValue;
  }
}

核心注意点:所有返回Future的异步方法,如果你需要依赖它内部的执行结果,必须使用await等待方法执行完成,否则代码会直接跳过异步逻辑往下执行,永远拿不到你预期的赋值结果。

内容的提问来源于stack exchange,提问作者Jibi Joseph

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:09:23