在 Flutter 中加载 http 请求之前如何禁用按钮?

How to disable a button until http request is loaded in Flutter?

我正在尝试实现一个 flutter 应用程序以从 API 端点获取数据。我已经在按下按钮时实现了获取功能。

不过,我希望在获取请求时禁用按钮(以避免多次点击)!

我使用 dart http 包实现了它。

这是我的代码:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';

void main() => runApp(Home());

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  String _advice = '';
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('App 1'),
          centerTitle: true,
        ),
        body: Center(
          child: Container(
            padding: EdgeInsets.all(32.0),
            child: Column(
              children: <Widget>[
                // Text 1 - advice
                Container(
                  padding: EdgeInsets.all(16.0),
                  child: Text(
                    '$_advice',
                    style: TextStyle(
                      fontSize: 20.0,
                    ),
                  ),
                ),

                // Text 2 - counter
                Text(
                  '$_counter',
                  style: TextStyle(fontSize: 50, fontWeight: FontWeight.bold),
                ),
              ],
            ),
          ),
        ),

        // Floating button
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.file_download),
          onPressed: _fetchPost,
        ),
      ),
    );
  }

  _fetchPost() async {
    final url = 'https://api.adviceslip.com/advice';
    final response = await http.get(url);
    dynamic body = json.decode(response.body);

    // If server returns an OK response, parse the JSON.
    if (response.statusCode == 200) {
      print(response.body);
      setState(() {
        _advice = body['slip']['advice'];
        _counter += 1;
      });
    }
    // If that response was not OK, throw an error.
    else {
      // throw Exception('Failed to load post');
      print('Failed to load post');
    }
  }
}

使用像 isLoading 这样的 属性 并在执行请求之前和之后设置它

您也可以通过将 onPressed 设置为 null 来禁用 FloatingActionButton。 (Learn More)

这是使用这种方法的代码

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';

void main() => runApp(Home());

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  String _advice = '';
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('App 1'),
          centerTitle: true,
        ),
        body: Center(
          child: Container(
            padding: EdgeInsets.all(32.0),
            child: Column(
              children: <Widget>[
                // Text 1 - advice
                Container(
                  padding: EdgeInsets.all(16.0),
                  child: Text(
                    '$_advice',
                    style: TextStyle(
                      fontSize: 20.0,
                    ),
                  ),
                ),

                // Text 2 - counter
                Text(
                  '$_counter',
                  style: TextStyle(fontSize: 50, fontWeight: FontWeight.bold),
                ),
              ],
            ),
          ),
        ),

        // Floating button
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.file_download),
          // You can disable the FAB by setting this property to null
          onPressed: isLoading ? null : _fetchPost,
        ),
      ),
    );
  }

  bool isLoading;
  setLoading(bool state) => setState(() => isLoading = state));

  _fetchPost() asnyc {
    try {
      setLoading(true);
      await _fetchData();
    } finally {
      setLoading(false);
    }
  }

  _fetchData() async {
    final url = 'https://api.adviceslip.com/advice';
    final response = await http.get(url);
    dynamic body = json.decode(response.body);

    // If server returns an OK response, parse the JSON.
    if (response.statusCode == 200) {
      print(response.body);
      setState(() {
        _advice = body['slip']['advice'];
        _counter += 1;
      });
    }
    // If that response was not OK, throw an error.
    else {
      // throw Exception('Failed to load post');
      print('Failed to load post');
    }
  }
}