Flutter 从Splash页跳转后TextField获焦触发页面重载问题求解
问题原因
- 核心错误是将
Future.delayed延迟跳转逻辑写在了SplashPage的build方法中:Flutter的build方法是纯渲染方法,会因为多种场景(比如键盘弹出导致视口尺寸变化、父组件重绘、系统配置变更)被多次触发,每次执行都会新增一个4秒后跳转登录页的异步任务。 - 跳转时使用了
Navigator.pushNamed而不是替换路由的API,导致SplashPage一直残留在路由栈中,即便跳转到登录页后,只要触发全量UI重绘(比如TextField获取焦点弹出键盘),栈底的SplashPage仍然会执行build方法,不断新增跳转任务,任务触发时就会不断压入新的登录页,表现为页面重载。 - 从Main页跳转登录页正常的原因是此时
SplashPage已经不在路由栈中,不会触发多余的跳转逻辑。
解决方案
修改SplashPage的实现,修正异步逻辑的位置和路由跳转方式:
- 将延迟跳转逻辑从
build方法移到initState中,initState只会在页面初始化时执行一次,不会重复触发。 - 跳转前加
mounted判断,避免页面销毁后执行逻辑抛出异常。 - 使用
Navigator.pushReplacementNamed替换当前路由,跳转后将SplashPage从路由栈中彻底移除,避免残留。
修改后的代码示例:
class SplashPage extends StatefulWidget { const SplashPage({super.key}); @override State<SplashPage> createState() => _SplashPageState(); } class _SplashPageState extends State<SplashPage> { @override void initState() { super.initState(); Future.delayed(const Duration(seconds: 4), () { if (!mounted) return; Navigator.pushReplacementNamed(context, "/login"); }); } @override Widget build(BuildContext context) { return const Scaffold( backgroundColor: Palette.white, body: Center( child: SizedBox(height: 60, width: 60, child: CircularProgressIndicator()), ), ); } }
内容的提问来源于stack exchange,提问作者Atras VidA
相关产品推荐
相关产品推荐

