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

Flutter中点击SfDataGrid行跳转至用户详情页的实现方法

实现SfDataGrid行点击跳转到用户详情页(Firestore数据源)

核心思路

通过给SfDataGrid绑定行点击回调,获取选中行的用户ID(或完整用户对象),再用MaterialPageRoute跳转到详情页,最终基于ID从Firestore拉取完整信息展示。


步骤1:给SfDataGrid添加行点击事件

利用SfDataGrid的onRowTap回调获取点击行的用户数据,触发页面跳转:

SfDataGrid(
  source: _userDataSource,
  columns: [
    GridColumn(columnName: 'name', label: const Text('姓名')),
    GridColumn(columnName: 'email', label: const Text('邮箱')),
    // 其他列定义
  ],
  // 行点击回调
  onRowTap: (RowTapDetails details) {
    // 从数据源中拿到选中的用户对象
    final UserModel selectedUser = _userDataSource.data[details.rowIndex];
    // 跳转到详情页
    Navigator.push(
      context,
      MaterialPageRoute(
        // 传递用户ID或完整对象,二选一即可
        builder: (context) => UserDetailScreen(userId: selectedUser.id),
        // builder: (context) => UserDetailScreen(user: selectedUser),
      ),
    );
  },
)

步骤2:确保DataGridSource保留完整用户数据

自定义DataGridSource时,要存储完整的用户对象(包含Firestore文档ID),方便点击时直接获取:

class UserDataSource extends DataGridSource {
  UserDataSource(this.data) {
    _buildRows();
  }

  // 存储完整的用户列表
  final List<UserModel> data;
  late List<DataGridRow> _rows;

  void _buildRows() {
    _rows = data.map((user) {
      return DataGridRow(cells: [
        DataGridCell<String>(columnName: 'name', value: user.name),
        DataGridCell<String>(columnName: 'email', value: user.email),
        // 其他对应列的单元格数据
      ]);
    }).toList();
  }

  @override
  List<DataGridRow> get rows => _rows;

  @override
  DataGridRowAdapter buildRow(DataGridRow row) {
    return DataGridRowAdapter(
      cells: row.getCells().map((cell) {
        return Container(
          alignment: Alignment.center,
          padding: const EdgeInsets.all(8),
          child: Text(cell.value.toString()),
        );
      }).toList(),
    );
  }
}

同时,从Firestore拉取数据时要保存文档ID到用户实体类:

// 用户实体类
class UserModel {
  final String id;
  final String name;
  final String email;
  // 其他字段

  UserModel({
    required this.id,
    required this.name,
    required this.email,
    // 其他字段初始化
  });
}

// 从Firestore获取用户数据的方法
Future<List<UserModel>> fetchUsers() async {
  final snapshot = await FirebaseFirestore.instance.collection('users').get();
  return snapshot.docs.map((doc) {
    return UserModel(
      id: doc.id, // 保存Firestore文档ID
      name: doc['name'],
      email: doc['email'],
      // 映射其他字段
    );
  }).toList();
}

步骤3:实现用户详情页

两种实现方式,选其一即可:

方式1:通过ID从Firestore重新拉取数据

适合用户信息可能实时更新的场景:

class UserDetailScreen extends StatelessWidget {
  final String userId;

  const UserDetailScreen({super.key, required this.userId});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('用户详情')),
      body: FutureBuilder<DocumentSnapshot>(
        future: FirebaseFirestore.instance.collection('users').doc(userId).get(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }
          if (!snapshot.hasData || !snapshot.data!.exists) {
            return const Center(child: Text('用户不存在'));
          }
          final userData = snapshot.data!.data() as Map<String, dynamic>;
          return Padding(
            padding: const EdgeInsets.all(16),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text('姓名: ${userData['name']}', style: const TextStyle(fontSize: 18)),
                const SizedBox(height: 8),
                Text('邮箱: ${userData['email']}', style: const TextStyle(fontSize: 18)),
                const SizedBox(height: 8),
                Text('电话: ${userData['phone'] ?? '无'}', style: const TextStyle(fontSize: 18)),
                // 展示更多用户字段
              ],
            ),
          );
        },
      ),
    );
  }
}

方式2:直接传递完整用户对象

适合数据量小、无需实时更新的场景,无需再次请求Firestore:

class UserDetailScreen extends StatelessWidget {
  final UserModel user;

  const UserDetailScreen({super.key, required this.user});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(user.name)),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('邮箱: ${user.email}', style: const TextStyle(fontSize: 18)),
            const SizedBox(height: 8),
            Text('电话: ${user.phone ?? '无'}', style: const TextStyle(fontSize: 18)),
            // 直接使用user对象的字段展示
          ],
        ),
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 11:45:29