简体   繁体   English

按下按钮禁用按钮但不重建整个屏幕

[英]disable button with press but without rebuilding the whole screen

I have a quiz screen where I am using an API with FutureBuilder .我有一个测验屏幕,我在其中使用APIFutureBuilder 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.

相关问题 如何在按下按钮的情况下将数据加载到屏幕上而不路由和重建整个屏幕 - How to load data on a screen on the press of a button without routing and rebuilding whole screen Flutter:在屏幕中更改卡片而不重建整个页面 - Flutter: Changing Cards in Screen without rebuilding the whole page 如何在不重建 flutter 中的整个页面的情况下从屏幕上删除一个小部件 - How to remove a widget from the screen without rebuilding the whole page in flutter 如何在不重建整个页面的情况下使用 mobx 更改 ListTile 数据#Flutter - How to change ListTile data with mobx without rebuilding the whole page #Flutter 如何在不重建整个列表的情况下更新列表项 - how can i update list item without rebuilding whole list Flutter web,在 Tab 按下时禁用按钮焦点 - Flutter web, disable focus on button on Tab press 如何根据用户单击的项目返回不同的 Sliver 而无需重建整个 StatefullWidget - How can i return diffrent Sliver depending on which item the user clicked without rebuilding the whole StatefullWidget flutter中的按钮占据整个屏幕 - Button taking up whole screen in flutter 避免使用 Future builder 重建屏幕 - Avoid rebuilding screen with Future builder 如何禁用在标签栏内滑动整个屏幕? - How to disable swiping whole screen inside the Tab Bar?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM