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

Flutter+Supabase实现ListView.builder跳转详情页并传参

解决ListView.builder跳转详情页传递数据的方案

1. 改造详情页,添加数据接收能力

让PageDetail通过构造函数接收列表项数据,示例如下:

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

  // 构造函数,强制传入数据
  const PageDetail({super.key, required this.itemData});

  @override
  Widget build(BuildContext context) {
    // 在详情页中直接使用itemData渲染内容
    return Scaffold(
      appBar: AppBar(title: Text(itemData['date'])),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('日期: ${itemData['date']}'),
            Text('时间: ${itemData['heure']}'),
            // 根据数据库字段添加其他展示内容
          ],
        ),
      ),
    );
  }
}

2. 在列表点击事件中传递对应索引的数据

回到列表页面,修改InkWell的onTap回调,跳转时传入当前列表项的数据:

// 替换原有的onTap代码
onTap: () => Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => PageDetail(itemData: items[index]),
  ),
),

3. 进阶优化:用实体类替代Map(可选)

如果数据结构固定,推荐创建实体类封装数据,提升代码可读性与类型安全性:

第一步:创建实体类

class MyItem {
  final String id;
  final String date;
  final String heure;
  // 根据数据库表结构添加其他字段

  MyItem({
    required this.id,
    required this.date,
    required this.heure,
  });

  // 从Map转换为实体类的方法
  factory MyItem.fromMap(Map<String, dynamic> map) {
    return MyItem(
      id: map['id'] as String,
      date: map['date'] as String,
      heure: map['heure'] as String,
    );
  }
}

第二步:转换Stream中的数据类型

修改Supabase流,将Map列表转为实体类列表:

// 更新流定义
final _mySupabaseTable = Supabase.instance.client
    .from('xxx')
    .stream(primaryKey: ['id'])
    .order('id', ascending: false)
    .map((maps) => maps.map(MyItem.fromMap).toList());

// 对应修改StreamBuilder的泛型
StreamBuilder<List<MyItem>>(
  stream: _mySupabaseTable,
  builder: (context, snapshot) {
    if (!snapshot.hasData) {
      return const Center(child: CircularProgressIndicator());
    }
    final items = snapshot.data!;
    return ListView.builder(
      itemCount: items.length,
      itemBuilder: (context, index) {
        final currentItem = items[index];
        return InkWell(
          onTap: () => Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => PageDetail(item: currentItem),
            ),
          ),
          child: Card(
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  ListTile(
                    title: Text('${currentItem.date} / ${currentItem.heure}',
                      style: const TextStyle(fontSize: 12.0, color: Colors.grey),),
                    trailing: const Icon(Icons.arrow_forward_ios),
                  ),
                ],
              ),
            ),
          ),
        );
      },
    );
  },
)

第三步:修改详情页接收实体类

class PageDetail extends StatelessWidget {
  final MyItem item;

  const PageDetail({super.key, required this.item});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(item.date)),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('日期: ${item.date}'),
            Text('时间: ${item.heure}'),
          ],
        ),
      ),
    );
  }
}

核心逻辑是通过详情页的构造函数接收参数,在跳转时传入对应索引的列表数据,两种方式都能实现需求,实体类方案更适合中大型项目。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:23:16