[英]disable button with press but without rebuilding the whole screen
I have a quiz screen where I am using an API
with FutureBuilder
.我有一个测验屏幕,我在其中使用API
和FutureBuilder
。 Each time build
method is refreshed, the new question is fetched.每次刷新build
方法时,都会获取新问题。 There's a submit button at the bottom to save the response and reset the screen.底部有一个提交按钮,用于保存响应并重置屏幕。 What I want to do is to disable
the submit button until new question is fetched after pressing the submit button and make enabled when new question is rebuild.我想要做的是disable
提交按钮,直到在按下提交按钮后获取新问题,并在重建新问题时启用。 I cannot call the setstate to make it null with a bool variable because new question is loaded due to this.我无法使用 bool 变量调用 setstate 使其成为 null,因为因此加载了新问题。 Here's my code to reproduce the issue:这是我重现问题的代码:
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 ;
getQuestion () {}
@override
Widget build(BuildContext context) {
print(buildCount);
print('Question Fetched and UI is building');
return SafeArea(child: Scaffold(
body: FutureBuilder(
future: getQuestion(),
builder: (context, snapshot){
return ListView(
children: [
ListTile(title: Text('Quiz Title'),),
ListTile(title: Text('1'),),
ListTile(title: Text('2'),),
ListTile(title: Text('3'),),
ListTile(title: Text('4'),),
SizedBox(height: 20,),
ElevatedButton(
onPressed: () async {
print('Please Wait, Answer is getting Saved');
// Button Should be shown disabled for 3 seconds
await Future.delayed(const Duration(seconds: 3));
buildCount++;
setState(() {
// this setState rebuilds the screen and new question is loaded
// because of future builder
});
}, child: Text('Submit Quiz'))
],
);
},
),
));
}
}
When you are getting data from API check if you have data in your variable, if has data return data if not then call API,当您从 API 获取数据时,检查您的变量中是否有数据,如果有数据返回数据,如果没有则调用 API,
update: with _submitEnabled value.更新:使用 _submitEnabled 值。
Here example:这里的例子:
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class QuizForm extends StatefulWidget {
const QuizForm({Key? key}) : super(key: key);
@override
State<QuizForm> createState() => _QuizFormState();
}
class _QuizFormState extends State<QuizForm> {
Question _cachedQuestion;
bool _submitEnabled = false;
Future<Question> getQuestion() async {
if (_cachedQuestion != null) {
return _cachedQuestion;
}
final response = await http.get('https://your-api-endpoint.com/question');
if (response.statusCode == 200) {
final question = Question.fromJson(json.decode(response.body));
_cachedQuestion = question;
_submitEnabled = true;
return question;
} else {
throw Exception('Failed to fetch question');
}
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: FutureBuilder(
future: getQuestion(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final question = snapshot.data;
return ListView(
children: [
ListTile(title: Text(question.title)),
ListTile(title: Text(
I managed to get it through ValueListenableBuilder
.我设法通过ValueListenableBuilder
获得它。 Here is my code that is working as expected:这是我按预期工作的代码:
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> {
final _buttonEnabled = ValueNotifier(true);
int buildCount = 0;
getQuestion () {}
@override
Widget build(BuildContext context) {
print(buildCount);
return SafeArea(
child: Scaffold(
body: FutureBuilder(
future: getQuestion(),
builder: (context, snapshot) {
return ListView(
children: [
ListTile(title: Text('Quiz Title')),
ListTile(title: Text('1')),
ListTile(title: Text('2')),
ListTile(title: Text('3')),
ListTile(title: Text('4')),
SizedBox(height: 20),
ValueListenableBuilder(
valueListenable: _buttonEnabled,
builder: (context, value, child) {
return ElevatedButton(
onPressed: _buttonEnabled.value
? () async {
_buttonEnabled.value = false;
print('Please Wait, Answer is getting Saved');
await Future.delayed(const Duration(seconds: 3));
_buttonEnabled.value = true;
buildCount++;
setState(() {
});
}
: null,
child: child,
);
},
child: Text('Submit Quiz'),
),
],
);
},
),
),
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.