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

Flutter Web+Firebase:点击ListTile在侧边容器展示用户详情(不跳转)

实现点击ListTile在右侧展示用户详情(无需跳转页面)

核心结论

完全不需要跳转页面,通过状态管理保存当前选中的用户数据,就能在当前页面的右侧容器动态渲染用户详情。

具体实现步骤

  1. 添加状态变量:在_AllUserScreenState类中声明变量,存储当前选中的用户文档:
DocumentSnapshot<Map<String, dynamic>>? selectedUser;
  1. 绑定点击事件:给ListTile的onTap回调添加逻辑,更新选中状态并触发页面重绘:
onTap: () {
  setState(() {
    selectedUser = snapshot.data!.docs[index];
  });
},
  1. 渲染右侧详情容器:根据selectedUser的状态展示不同内容——未选中时显示提示,选中时展示用户详细信息。

修改后的完整代码

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';

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

  @override
  State<AllUserScreen> createState() => _AllUserScreenState();
}

class _AllUserScreenState extends State<AllUserScreen> {
  // 存储选中的用户文档
  DocumentSnapshot<Map<String, dynamic>>? selectedUser;

  @override
  Widget build(BuildContext context) {
    final screenHeight = MediaQuery.of(context).size.height;
    final screenWidth = MediaQuery.of(context).size.width;

    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: const Text(
          'All Users',
          textAlign: TextAlign.center,
          style: TextStyle(fontSize: 30, color: Colors.green),
        ),
        backgroundColor: Colors.transparent,
        elevation: 0,
        leading: IconButton(
            onPressed: () {
              Navigator.pop(context);
            },
            icon: const Icon(
              Icons.arrow_back_ios,
              color: Colors.green,
            )),
      ),
      body: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          SizedBox(
            width: screenWidth * 0.4,
            child: StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
              stream: FirebaseFirestore.instance.collection('users').snapshots(),
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  return ListView.builder(
                    itemCount: snapshot.data!.docs.length,
                    itemBuilder: (context, index) {
                      final user = snapshot.data!.docs[index];
                      return Card(
                        // 选中时高亮卡片,提升交互体验
                        color: selectedUser?.id == user.id ? Colors.green.shade50 : null,
                        child: ListTile(
                          onTap: () {
                            setState(() {
                              selectedUser = user;
                            });
                          },
                          title: Text(
                            user.get('Full name'),
                          ),
                        ),
                      );
                    },
                  );
                }
                if (snapshot.hasError) {
                  return const Text('加载出错');
                } else {
                  return const Center(child: CircularProgressIndicator());
                }
              },
            ),
          ),
          SizedBox(
            width: screenWidth * 0.03,
          ),
          Container(
            width: screenWidth * 0.4,
            color: Colors.grey.shade100,
            padding: const EdgeInsets.all(16),
            child: selectedUser == null
                ? const Center(
                    child: Text(
                      '请选择一个用户查看详情',
                      style: TextStyle(fontSize: 18, color: Colors.grey),
                    ),
                  )
                : Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        '姓名: ${selectedUser!.get('Full name')}',
                        style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                      ),
                      const SizedBox(height: 16),
                      Text('邮箱: ${selectedUser!.get('email')}'),
                      // 根据你的Firestore字段,添加更多详情展示
                      const SizedBox(height: 16),
                      Text('UID: ${selectedUser!.id}'),
                      // 其他字段比如电话、地址等,按需添加
                    ],
                  ),
          )
        ],
      ),
    );
  }
}

额外优化建议

  • 给选中卡片添加高亮样式,让用户直观感知当前选中项
  • 右侧容器添加内边距,优化详情内容排版
  • 根据Firestore实际存储的字段,扩展更多详情展示项

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:57:45