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

Flutter中点击GridView单元格跳转页面同时向其他页面传参如何通过Navigator实现

Flutter Navigator实现跨非跳转页面传值方案

针对你提到的点击GridView单元格跳转新页面,同时将单元格ID传给非本次跳转页面的需求,可根据你的实际场景选择以下三种基于Navigator原生能力的实现方式,无需引入第三方依赖:

场景说明

当前路由栈为【承载GridView的页面X】,点击单元格后栈变为【页面X → 本次跳转的目标页面A】,你需要传递ID的目标页面B不在本次跳转链路中,分为两种子场景:B是未来要打开的新页面、B已经在路由栈中。


方案1:状态暂存+后续跳转传参(适配B是未来打开的新页面场景)

先将选中的ID存在当前页面X的状态中,后续跳转到B时通过Navigator的参数能力直接传递即可:

// 页面X的状态类中定义存储变量
String? _selectedCellId;

// GridView单元格点击逻辑
GridView.builder(
  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
  itemCount: 20,
  itemBuilder: (context, index) {
    final cellId = "cell_$index";
    return GestureDetector(
      onTap: () {
        // 暂存选中的ID
        _selectedCellId = cellId;
        // 跳转本次要展示的页面A
        Navigator.push(context, MaterialPageRoute(builder: (ctx) => const PageA()));
      },
      child: Center(child: Text("单元格$index")),
    );
  }
)

后续跳转到页面B时传递参数:

// 页面X中触发跳转B的逻辑
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (ctx) => PageB(),
    // 传递参数
    settings: RouteSettings(arguments: _selectedCellId),
  )
);

// 页面B中接收参数
@override
Widget build(BuildContext context) {
  final String? cellId = ModalRoute.of(context)?.settings.arguments as String?;
  return Scaffold(body: Center(child: Text("收到的ID:$cellId")));
}

方案2:RouteObserver监听回传(适配B已经在路由栈中的场景)

如果B已经在路由栈中(如路由栈为【页面B → 页面X】),可以通过Flutter自带的RouteObserver监听路由切换事件实现回传:

  1. 全局定义RouteObserver并注册到MaterialApp
// 全局声明
final RouteObserver<ModalRoute> routeObserver = RouteObserver<ModalRoute>();

// 注册到MaterialApp
MaterialApp(
  navigatorObservers: [routeObserver],
  // 其余配置不变
)
  1. 页面B订阅路由事件
class PageB extends StatefulWidget {
  const PageB({super.key});

  @override
  State<PageB> createState() => _PageBState();
}

class _PageBState extends State<PageB> with RouteAware {
  String? _receivedCellId;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // 订阅路由事件
    routeObserver.subscribe(this, ModalRoute.of(context)!);
  }

  @override
  void dispose() {
    // 取消订阅
    routeObserver.unsubscribe(this);
    super.dispose();
  }

  // 从上层页面退回到当前页面时触发
  @override
  void didPopNext() {
    final cellId = ModalRoute.of(context)?.settings.arguments as String?;
    if (cellId != null) {
      setState(() => _receivedCellId = cellId);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(body: Center(child: Text("收到的ID:$_receivedCellId")));
  }
}
  1. 页面X点击单元格时更新路由参数
onTap: () {
  final cellId = "cell_$index";
  // 将ID存入当前页面X的路由参数中
  ModalRoute.of(context)?.settings = RouteSettings(arguments: cellId);
  // 跳转页面A
  Navigator.push(context, MaterialPageRoute(builder: (ctx) => const PageA()));
}

方案3:全局路由参数池(适配所有场景)

如果不想区分场景,可以维护一个全局的路由参数映射表,所有跨页面传值都通过这个表存取,实现最简单:

// 全局定义参数池
final Map<String, dynamic> globalRouteParams = {};

// GridView点击逻辑
onTap: () {
  final cellId = "cell_$index";
  globalRouteParams["selectedCellId"] = cellId;
  Navigator.push(context, MaterialPageRoute(builder: (ctx) => const PageA()));
}

// 页面B中取值
final String? cellId = globalRouteParams["selectedCellId"];
// 用完可以删除避免内存泄漏
globalRouteParams.remove("selectedCellId");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 20:39:04