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

Kivy:如何在多个屏幕之间传递用户信息

Hey, great question! Let's break down a few straightforward ways to pass that user data from your login screen to the UserInfoPage so you can use it in show_info().

解决方案

方案1:导航跳转时直接传递参数

这是最简单直接的方法,适合小型应用或者只需要在两个屏幕间传递数据的场景。

步骤1:修改UserInfoPage的构造函数,接收数据

让第二个屏幕的构造函数接受你从findAccount拿到的records变量:

class UserInfoPage extends StatelessWidget {
  // 定义接收数据的变量
  final List<Map<String, dynamic>> userRecords;

  // 构造函数要求必须传入该参数
  const UserInfoPage({super.key, required this.userRecords});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('User Info')),
      body: Center(
        child: ElevatedButton(
          onPressed: showInfo,
          child: const Text('Show My Info'),
        ),
      ),
    );
  }

  void showInfo() {
    // 现在可以直接使用userRecords变量啦!
    print('User Info: $userRecords');
    // 这里写你的展示逻辑,比如弹窗、列表展示等
  }
}

步骤2:登录验证成功后,跳转时传递数据

在第一个屏幕的登录逻辑里,当findAccount返回有效records时,跳转到UserInfoPage并把数据传过去:

// 假设你已经完成SQLite查询,拿到了records
var records = await findAccount(usernameController.text, passwordController.text);

if (records.isNotEmpty) {
  // 验证成功,跳转并传递records
  Navigator.push(
    context,
    MaterialPageRoute(
      builder: (context) => UserInfoPage(userRecords: records),
    ),
  );
}

方案2:封装数据库服务+持久化登录状态

如果你的应用需要在多个屏幕共享用户信息,或者希望代码更解耦,可以把数据库操作抽成单独的服务类,同时保存登录用户的标识(比如用户名),在第二个屏幕重新查询数据。

步骤1:创建数据库服务类

把findAccount这类操作封装到单独的类里,方便全局调用:

class AccountDatabaseService {
  // 初始化数据库的逻辑(省略,你应该已经有这部分代码)
  static Future<Database> get _database async {
    // 返回你的SQLite数据库实例
  }

  // 验证用户名密码的方法
  static Future<List<Map<String, dynamic>>> findAccount(String username, String password) async {
    final db = await _database;
    return db.query(
      'users',
      where: 'username = ? AND password = ?',
      whereArgs: [username, password]
    );
  }

  // 根据用户名查询用户信息的方法
  static Future<List<Map<String, dynamic>>> getAccountByUsername(String username) async {
    final db = await _database;
    return db.query(
      'users',
      where: 'username = ?',
      whereArgs: [username]
    );
  }
}

步骤2:登录成功后保存用户名

用SharedPreferences持久化登录用户的用户名(也可以用内存变量,但重启APP会丢失):

var records = await AccountDatabaseService.findAccount(username, password);
if (records.isNotEmpty) {
  // 保存用户名到SharedPreferences
  SharedPreferences prefs = await SharedPreferences.getInstance();
  await prefs.setString('logged_in_username', username);

  // 跳转到UserInfoPage
  Navigator.push(context, MaterialPageRoute(builder: (context) => UserInfoPage()));
}

步骤3:在UserInfoPage中获取数据

在show_info()方法里,读取保存的用户名,再调用数据库服务获取用户信息:

void showInfo() async {
  // 读取保存的用户名
  SharedPreferences prefs = await SharedPreferences.getInstance();
  String? loggedInUsername = prefs.getString('logged_in_username');

  if (loggedInUsername != null) {
    // 重新查询用户信息
    var records = await AccountDatabaseService.getAccountByUsername(loggedInUsername);
    // 处理展示逻辑
    print('User Info: $records');
  }
}

方案3:使用全局状态管理(适合中大型应用)

如果你的应用有很多屏幕需要共享用户状态,推荐用状态管理工具(比如Provider、GetX)来统一管理用户数据。

示例:用Provider实现

  1. 创建状态管理类:
class UserProvider extends ChangeNotifier {
  List<Map<String, dynamic>>? _userRecords;

  List<Map<String, dynamic>>? get userRecords => _userRecords;

  // 设置用户信息并通知监听者
  void setUserRecords(List<Map<String, dynamic>> records) {
    _userRecords = records;
    notifyListeners();
  }
}
  1. 在APP入口注册Provider:
void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => UserProvider(),
      child: const MyApp(),
    ),
  );
}
  1. 登录成功后更新状态:
var records = await findAccount(username, password);
if (records.isNotEmpty) {
  // 更新全局状态
  Provider.of<UserProvider>(context, listen: false).setUserRecords(records);
  // 跳转页面
  Navigator.push(context, MaterialPageRoute(builder: (context) => UserInfoPage()));
}
  1. 在UserInfoPage中获取状态数据:
void showInfo() {
  // 从全局状态获取用户信息
  var userRecords = Provider.of<UserProvider>(context, listen: false).userRecords;
  if (userRecords != null) {
    // 处理展示逻辑
    print('User Info: $userRecords');
  }
}
总结
  • 如果你只是简单的两个屏幕传数据,方案1最适合,快速上手。
  • 如果需要多屏幕共享或解耦代码,方案2更灵活。
  • 中大型应用推荐方案3,状态管理更规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:19:15