Flutter实现提交后禁用按钮,直至新问题加载且不提前重建页面
解决Flutter测验页面提交按钮禁用问题
核心问题分析
原代码存在两个关键问题:
- 每次
build调用getQuestion(),导致页面重建时重复发起请求,且无法通过普通状态变量控制按钮禁用(因为setState会触发提前加载新问题) - 提交后无法精准控制按钮禁用状态,直到新问题完全加载完成
解决方案
1. 重构Future管理,避免重复请求
将getQuestion()的结果存储为状态变量,仅在初始化或提交答案后主动更新,而非在build中直接调用,防止不必要的重复请求。
2. 用状态变量控制按钮禁用
添加_isSubmitting变量标记提交状态,点击提交后立即设为true禁用按钮,待新问题加载完成后再设为false恢复可用。
完整修改代码
import 'package:flutter/material.dart'; class QuizForm extends StatefulWidget { const QuizForm({Key? key}) : super(key: key); @override State<QuizForm> createState() => _QuizFormState(); } class _QuizFormState extends State<QuizForm> { int buildCount = 0; late Future _questionFuture; bool _isSubmitting = false; // 模拟API请求获取题目 Future getQuestion() async { // 替换为实际API请求逻辑 await Future.delayed(const Duration(seconds: 1)); return "新题目数据"; } @override void initState() { super.initState(); // 初始化时加载第一个题目 _questionFuture = getQuestion(); } @override Widget build(BuildContext context) { print(buildCount); print('UI正在构建'); return SafeArea( child: Scaffold( body: FutureBuilder( future: _questionFuture, builder: (context, snapshot) { // 题目加载完成后重置提交状态 if (snapshot.connectionState == ConnectionState.done && _isSubmitting) { setState(() { _isSubmitting = false; }); } // 处理加载状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } return ListView( children: [ const ListTile(title: Text('Quiz Title')), const ListTile(title: Text('1')), const ListTile(title: Text('2')), const ListTile(title: Text('3')), const ListTile(title: Text('4')), const SizedBox(height: 20), ElevatedButton( onPressed: _isSubmitting ? null : () async { print('正在保存答案,请等待'); // 标记提交状态,禁用按钮 setState(() { _isSubmitting = true; }); // 模拟保存答案的API请求 await Future.delayed(const Duration(seconds: 3)); buildCount++; // 更新题目Future,触发FutureBuilder加载新题目 setState(() { _questionFuture = getQuestion(); }); }, child: const Text('提交测验'), ) ], ); }, ), ), ); } }
关键修改点说明
_questionFuture变量:存储题目请求的Future,仅在初始化和提交后更新,避免build时重复发起请求_isSubmitting状态:点击提交后立即设为true禁用按钮,待新题目加载完成(snapshot.connectionState == ConnectionState.done)后自动重置为false- FutureBuilder状态处理:在builder中判断题目加载状态,显示加载指示器,同时处理提交状态的重置
内容的提问来源于stack exchange,提问作者Tahir
相关产品推荐
相关产品推荐

