我正在努力更好地理解《Flutter 中的期货》.在本例中,我的应用程序进行API调用以获取一些类型为Future<String>的信息.我想在Text()小部件中显示此信息.然而,因为我的String被包装在Future中,所以我无法将此信息放入Text()小部件中,如果不求助于FutureBuilder来创建小部件树,我不确定如何处理这一问题.

下面的示例使用FutureBuilder,它工作得很好.请注意,我已注释掉底部附近的以下行:

Future<String> category = getData();

有没有可能把category变成String,然后简单地把它放到我的Text()小部件中?

import 'package:flutter/material.dart';
import 'cocktails.dart';

class CocktailScreen extends StatefulWidget {
  const CocktailScreen({super.key});

  @override
  State<CocktailScreen> createState() => _CocktailScreenState();
}

class _CocktailScreenState extends State<CocktailScreen> {
  @override
  Widget build(BuildContext context) {
    Cocktails cocktails = Cocktails();

    Future<String> getData() async {
      var data = await cocktails.getCocktailByName('margarita');
      String category = data['drinks'][0]['strCategory'];
      print('Category: ${data["drinks"][0]["strCategory"]}');
      return category;
    }

    FutureBuilder categoryText = FutureBuilder(
      initialData: '',
      future: getData(),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.hasData) {
            return Text(snapshot.data);
          } else if (snapshot.hasError) {
            return Text(snapshot.error.toString());
          }
        }
        return const CircularProgressIndicator();
      },
    );

    //Future<String> category = getData();

    return Center(
      child: categoryText,
    );
  }
}

以下是我的Cocktails节课:

import 'networking.dart';

const apiKey = '1';
const apiUrl = 'https://www.thecocktaildb.com/api/json/v1/1/search.php';

class Cocktails {
  Future<dynamic> getCocktailByName(String cocktailName) async {
    NetworkHelper networkHelper =
        NetworkHelper('$apiUrl?s=$cocktailName&apikey=$apiKey');
    dynamic cocktailData = await networkHelper.getData();
    return cocktailData;
  }
}

下面是我的NetworkHelper个班级:

import 'package:http/http.dart' as http;
import 'dart:convert';

class NetworkHelper {
  NetworkHelper(this.url);

  final String url;

  Future<dynamic> getData() async {
    http.Response response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      String data = response.body;
      var decodedData = jsonDecode(data);
      return decodedData;
    } else {
      //print('Error: ${response.statusCode}');
      throw 'Sorry, there\'s a problem with the request';
    }
  }
}

推荐答案

最好的方法是使用FutureBuilder:

FutureBuilder categoryText = FutureBuilder<String>(
        future: getData(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              return Text('Loading....');
            default:
              if (snapshot.hasError) {
                return Text('Error: ${snapshot.error}');
              } else {
                var data = snapshot.data ?? '';

                return Text(data);
              }
          }
        },
      ),

但是,如果您不想使用FutureBuilder,请首先定义一个如下所示的字符串变量,并将adasd更改为:

String category = '';

Future<void> getData() async {
  var data = await cocktails.getCocktailByName('margarita');
  setState(() {
     category = data['drinks'][0]['strCategory'];
  });
}

然后在initState中调用它:

@override
  void initState() {
    super.initState();
    getData();
  }

并像这样使用它:

@override
  Widget build(BuildContext context) {
    return Center(
      child: Text(category),
    );
  }

remember在构建方法之外定义categorygetDatacocktails,而不是在其内部.

Flutter相关问答推荐

Flutter FireRestore:如何从特定/实际领域获取数据

如何在列表磁贴上添加行

在Flutter 中压缩图片返回空

audioQuery不会等待判断存储权限

Flutter 隔离.使用多个参数运行

在Fighter中,我如何在窗口的顶部和底部排列Widget?

任务';:app:check DebugDuplicateClasss';的Ffltter Share_plus抛出执行失败

Flutter卡内容未在水平列表视图中居中

Flutter中不使用Container是否可以做margin

在 Flutter 中使用条件语句设置 ImageProvider Object 类型的背景图像

Flutter Dismissible 不会在 startToEnd 滑动时被关闭

如何将取消图标放置在右上角

如何在Flutter中的textField中在可编辑文本和前缀图标之间添加空格?

Flutter Dart 功能弹出错误的小部件?

flutter 中 // 和 /// 有什么区别

如何流畅切换画面?

如何从 Firebase `get()` 获取 `DocumentReference`

Pub get 尚未运行

如何使按钮被选中?

NoSuchMethodError:方法 '[]' 在 null 上被调用.我的信息流中的错误