Flutter中ElevatedButton的onPressed函数自动执行问题排查
问题分析:测验应用首页直接跳转至最后科目页面
问题描述
我正在开发一款测验应用,首页提供科目选择功能,点击对应按钮后应展示该科目的测验题目。但运行代码时,首页未显示,直接展示了列表最后一个科目physics的测验页面。
相关代码片段
main.dart
import 'package:flutter/material.dart'; import './page.dart'; import './s_button.dart'; class _MyAppState extends State<MyApp> { List subjects = ["biology", "chemistry", "physics"]; bool PageIndex = true; String selected_subject = ""; void changePage(s) { WidgetsBinding.instance.addPostFrameCallback((_) { setState(() { selected_subject = s; PageIndex = false; }); }); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( backgroundColor: Colors.pink[100], body: PageIndex ? Center( child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Text("Quiz App", style: TextStyle(fontSize: 24)), SizedBox(height: 30), Text("Select a subject"), SizedBox(height: 40), ...subjects.map((sub){ return SubjectButton(pageHandler: changePage, subject: sub); }) ] ), ) : QuizPage(selected_subject) ) ); } }
s_button.dart
import 'package:flutter/material.dart'; class SubjectButton extends StatelessWidget { final Function pageHandler; final String subject; const SubjectButton({Key? key, required this.pageHandler, required this.subject}) : super(key: key); @override Widget build(BuildContext context) { return Column( children: [ Container( width: 120, height: 60, child: ElevatedButton( style: ElevatedButton.styleFrom( primary: Colors.pink, elevation: 5, ), onPressed: pageHandler(subject), child: Text(subject) ) ), SizedBox(height: 20) ], ); } }
问题根源
核心问题在SubjectButton的onPressed赋值逻辑:
- 当前代码
onPressed: pageHandler(subject)会在Widget构建阶段直接执行pageHandler(subject)方法,而非等待按钮点击时触发。 - 遍历subjects列表时,三次调用
pageHandler,最后一次传入"physics"会把PageIndex设为false,导致页面一加载就直接切换到物理测验页面。 - 另外
main.dart中的WidgetsBinding.instance.addPostFrameCallback属于冗余代码,没必要在setState前加这个回调。
修复方案
- 修改
s_button.dart中的onPressed,改用匿名函数包裹,确保只有点击时才执行方法:
onPressed: () => pageHandler(subject),
- 简化
main.dart中的changePage方法,移除多余的回调:
void changePage(s) { setState(() { selected_subject = s; PageIndex = false; }); }
内容的提问来源于stack exchange,提问作者Diana
相关产品推荐
相关产品推荐

