【问题标题】:How to disable a button until http request is loaded in Flutter?如何在 Flutter 中加载 http 请求之前禁用按钮?
【发布时间】:2019-09-18 11:54:14
【问题描述】:

我正在尝试实现一个颤振应用程序来从 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');
    }
  }
}

【问题讨论】:

  • 您是否使用 bloc 模式,如果是,您可以将按钮包装在 Stream Builder 中。此 StreamBuilder 侦听“BehaviorSubject buttonEnabled”。启动请求时,您执行“buttonEnabled.sink.add(false);”。当请求完成时,您执行 'buttonEnabled.sink.add(true);'在 Button 中,您只需使用 snapshot.data 来启用参数。

标签: flutter httprequest


【解决方案1】:

使用 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');
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多