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

Flutter路由映射问题:Navigator.pushNamed触发index未定义错误

Flutter GridView 项点击跳转错误:index未定义的解决方法

错误原因分析

  • index作用域问题:你把GestureDetector放在了GridView.builder外面,这里的index是itemBuilder的局部参数,外层onTap根本访问不到该变量,所以报"index未定义"。
  • 路由参数类型错误:masterMap里的destination值不统一,有的是路由名称(比如InputRaw.id),有的直接传了InputRaw()(Widget实例),而Navigator.pushNamed需要传入命名路由的字符串名称,不能传Widget对象。

解决步骤

1. 统一路由名称格式

先确保每个页面都定义静态路由id(以InputRaw为例):

// 在InputRaw页面中添加静态路由标识
class InputRaw extends StatelessWidget {
  static const id = '/inputRaw';
  // ... 页面其他代码
}

然后将masterMap里的destination全部改为对应的路由名称字符串:

final List<Map<String, dynamic>> masterMap = [
  {'image': 'assets/images/raw.png', 'title': 'Input Raw', 'destination': InputRaw.id},
  {'image': 'assets/images/supplier.png', 'title': 'Input Supplier', 'destination': '/inputSupplier'},
  {'image': 'assets/images/cmt.png', 'title': 'Input CMT', 'destination': '/inputCMT'},
  // ... 其他项同理修改为对应页面的路由名称
];

2. 将点击事件移到每个网格项内部

把GestureDetector从GridView.builder外层移到itemBuilder内部,这样就能直接获取当前项的index:

修改后的完整代码:

import 'package:egarment2/pages/master_menu/input_raw.dart';
import 'package:flutter/material.dart';

class FeatureCard extends StatefulWidget {
  const FeatureCard({Key? key}) : super(key: key);

  @override
  State<FeatureCard> createState() => _FeatureCardState();
}

class _FeatureCardState extends State<FeatureCard> {
  final List<Map<String, dynamic>> masterMap = [
    {'image': 'assets/images/raw.png', 'title': 'Input Raw', 'destination': InputRaw.id},
    {'image': 'assets/images/supplier.png', 'title': 'Input Supplier', 'destination': '/inputSupplier'},
    {'image': 'assets/images/cmt.png', 'title': 'Input CMT', 'destination': '/inputCMT'},
    {'image': 'assets/images/pola.png', 'title': 'Input Pola', 'destination': '/inputPola'},
    {'image': 'assets/images/outlet.png', 'title': 'Input Outlet', 'destination': '/inputOutlet'},
    {'image': 'assets/images/product.png', 'title': 'Input Produk', 'destination': '/inputProduk'},
    {'image': 'assets/images/material.png', 'title': 'Input Jenis Material', 'destination': '/inputMaterial'},
    {'image': 'assets/images/warna.png', 'title': 'Input Warna', 'destination': '/inputWarna'},
    {'image': 'assets/images/qr.png', 'title': 'Input by QR', 'destination': '/inputQR'},
    {'image': 'assets/images/acc.png', 'title': 'Accessories', 'destination': '/inputAccessories'},
    {'image': 'assets/images/tools.png', 'title': 'Tools & Equipment', 'destination': '/inputTools'},
    {'image': 'assets/images/adjustment.png', 'title': 'Adjustments', 'destination': '/inputAdjustment'},
    {'image': 'assets/images/stock.png', 'title': 'Stock Opname', 'destination': '/inputStock'},
  ];

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        crossAxisSpacing: 12.0,
        mainAxisSpacing: 12.0,
      ),
      itemCount: masterMap.length,
      itemBuilder: (_, index) {
        return GestureDetector(
          onTap: () {
            String routeName = masterMap[index]['destination'];
            Navigator.pushNamed(context, routeName);
          },
          child: Padding(
            padding: const EdgeInsets.only(top: 40),
            child: Container(
              height: 175,
              width: 150,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(20),
                color: Colors.white,
              ),
              child: Column(
                children: [
                  Container(
                    padding: const EdgeInsets.all(20),
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(15),
                    ),
                    child: Image.asset(masterMap[index]['image']),
                  ),
                  Text(
                    masterMap[index]['title'],
                    style: const TextStyle(
                      fontFamily: 'Quicksand',
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      },
    );
  }
}

额外提示

  • 务必在MaterialApp的routes参数中注册所有用到的命名路由:
MaterialApp(
  routes: {
    InputRaw.id: (context) => const InputRaw(),
    '/inputSupplier': (context) => const InputSupplier(),
    // ... 其他页面路由注册
  },
);
  • 访问列表元素时,masterMap[index]['key']比masterMap.elementAt(index)['key']更简洁直观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 22:30:41