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

如何在Flutter中使用Shared Preference存储文本框的用户名和密码

实现从TextField获取数据并存储到SharedPreferences

要完成这个需求,你需要通过TextEditingController获取文本框输入,再结合按钮触发存储逻辑,具体步骤如下:

1. 添加TextEditingController实例

在_LoginState类中定义两个控制器,分别对应用户名和密码输入框:

final _usernameController = TextEditingController();
final _passwordController = TextEditingController();

2. 绑定控制器到TextField

给每个TextField设置controller属性,同时添加提示文本优化界面:

TextField(
  controller: _usernameController,
  decoration: const InputDecoration(hintText: '请输入用户名'),
),
const SizedBox(height: 16), // 添加间距优化布局
TextField(
  controller: _passwordController,
  decoration: const InputDecoration(hintText: '请输入密码'),
  obscureText: true, // 密码框隐藏输入内容
),

3. 添加保存按钮并调用存储函数

在Column中添加一个按钮,点击时获取控制器的文本,调用saveData函数。注意saveData是异步函数,需要用async/await处理:

const SizedBox(height: 24),
ElevatedButton(
  onPressed: () async {
    final username = _usernameController.text.trim();
    final password = _passwordController.text.trim();
    
    // 简单校验输入不为空
    if (username.isNotEmpty && password.isNotEmpty) {
      await saveData(username, password);
      // 保存成功提示
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('数据保存成功')),
      );
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('用户名和密码不能为空')),
      );
    }
  },
  child: const Text('登录并保存'),
),

4. 修正saveData函数的逻辑

你当前的saveData函数把用户名作为存储的键,会导致每次不同用户名生成新键,无法固定存储用户名和密码。应该用固定键名存储:

Future<void> saveData(String username, String password) async {
  final prefs = await SharedPreferences.getInstance();
  prefs.setString('username', username); // 固定键名'username'
  prefs.setString('password', password); // 固定键名'password'
}

5. 释放控制器资源

在组件销毁时释放控制器,避免内存泄漏:

@override
void dispose() {
  _usernameController.dispose();
  _passwordController.dispose();
  super.dispose();
}

完整的Login组件代码

class Login extends StatefulWidget {
  const Login({super.key});

  @override
  State<Login> createState() => _LoginState();
}

class _LoginState extends State<Login> {
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();

  Future<void> saveData(String username, String password) async {
    final prefs = await SharedPreferences.getInstance();
    prefs.setString('username', username);
    prefs.setString('password', password);
  }

  @override
  void dispose() {
    _usernameController.dispose();
    _passwordController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('LOGIN'),
      ),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(25.0),
            child: Container(
              height: 300,
              width: 500,
              color: Colors.black12,
              child: Padding(
                padding: const EdgeInsets.all(30.0),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    TextField(
                      controller: _usernameController,
                      decoration: const InputDecoration(hintText: '请输入用户名'),
                    ),
                    const SizedBox(height: 16),
                    TextField(
                      controller: _passwordController,
                      decoration: const InputDecoration(hintText: '请输入密码'),
                      obscureText: true,
                    ),
                    const SizedBox(height: 24),
                    ElevatedButton(
                      onPressed: () async {
                        final username = _usernameController.text.trim();
                        final password = _passwordController.text.trim();

                        if (username.isNotEmpty && password.isNotEmpty) {
                          await saveData(username, password);
                          ScaffoldMessenger.of(context).showSnackBar(
                            const SnackBar(content: Text('数据保存成功')),
                          );
                        } else {
                          ScaffoldMessenger.of(context).showSnackBar(
                            const SnackBar(content: Text('用户名和密码不能为空')),
                          );
                        }
                      },
                      child: const Text('登录并保存'),
                    ),
                  ],
                ),
              ),
            ),
          )
        ],
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Vidhu Prakash

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 09:02:29