Flutter空安全迁移问题:Route?无法传入Navigator.push
问题原因
你这段代码里,route被声明为可空类型Route?,但Navigator.push<T>的第二个参数要求的是非空的Route实例。空安全机制严格禁止将可空类型直接赋值给非空参数,哪怕逻辑上你确定route不会为null,编译器也会报错。
三种解决方法
方法1:非空断言(最简方案)
既然style是必填参数,且你已经覆盖了所有枚举分支(cupertino和material),逻辑上route绝对不会为null,直接用!告诉编译器“这个变量肯定非空”:
class Navigation { static Future<T?> navigateTo<T>({ required BuildContext context, required Widget screen, required NavigationRouteStyle style, }) async { Route? route; if (style == NavigationRouteStyle.cupertino) { route = CupertinoPageRoute<T>(builder: (_) => screen); } else if (style == NavigationRouteStyle.material) { route = MaterialPageRoute<T>(builder: (_) => screen); } // 添加!断言非空 return await Navigator.push<T>(context, route!); } }
方法2:提前初始化非空变量(更严谨)
直接把route声明为非空的Route<T>,通过switch或者if-else直接赋值,从根源避免可空问题。如果后续枚举新增值,switch还能强制你处理新分支,减少遗漏:
class Navigation { static Future<T?> navigateTo<T>({ required BuildContext context, required Widget screen, required NavigationRouteStyle style, }) async { final Route<T> route; switch (style) { case NavigationRouteStyle.cupertino: route = CupertinoPageRoute<T>(builder: (_) => screen); break; case NavigationRouteStyle.material: default: // 兜底处理枚举新增值,默认用Material样式 route = MaterialPageRoute<T>(builder: (_) => screen); } return await Navigator.push<T>(context, route); } }
方法3:使用late关键字(延迟初始化)
用late声明变量,告诉编译器“这个变量会在使用前完成初始化”,同样能避免可空类型的问题:
class Navigation { static Future<T?> navigateTo<T>({ required BuildContext context, required Widget screen, required NavigationRouteStyle style, }) async { late Route<T> route; if (style == NavigationRouteStyle.cupertino) { route = CupertinoPageRoute<T>(builder: (_) => screen); } else { // 覆盖material及可能的枚举新增值 route = MaterialPageRoute<T>(builder: (_) => screen); } return await Navigator.push<T>(context, route); } }
内容的提问来源于stack exchange,提问作者Tomasz Brzezina
相关产品推荐
相关产品推荐

