You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:如何在另一个类的Text Widget中展示API响应数据?

解决Flutter中API数据在Text Widget的展示问题

我已经通过GET方法成功获取了API数据,现在需要了解如何在另一个类的Text Widget中展示这些响应内容。以下是我使用的相关代码:

API调用类

const apiHost = 'andruxnet-random-famous-quotes.p.rapidapi.com';
const apiUrl = 'https://andruxnet-random-famous-quotes.p.rapidapi.com/';
const apiKey = '14b77a3e77msh224667c7b07c6edp170846jsn2144e4d9735f';

class Quote {
  static Future getQuote() async {
    var client = http.Client();
    var uri = Uri.parse(apiUrl);
    var response = await client.get(
      uri,
      headers: {'X-RapidAPI-Key': apiKey, 'X-RapidAPI-Host': apiHost},
    );
    if(response.statusCode == 200){
      var json = response.body;
      return getQuoteFromJson(json);
    }
    else {
      throw Exception(response.reasonPhrase);
    }
  }
}

数据模型类

import 'dart:convert';

List<GetQuote> getQuoteFromJson(String str) => List<GetQuote>.from(json.decode(str).map((x) => GetQuote.fromJson(x)));

String getQuoteToJson(List<GetQuote> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class GetQuote {
    GetQuote({
        required this.quoteText,
        required this.author,
    });

    String quoteText;
    String author;

    factory GetQuote.fromJson(Map<String, dynamic> e) => GetQuote(
        quoteText: e["quote"],
        author: e["author"],
    );

    Map<String, dynamic> toJson() => {
        "quote": quoteText,
        "author": author,
    };
}

UI代码

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

  @override
  State<QuotePage> createState() => _QuotePageState();
}

class _QuotePageState extends State<QuotePage> {

 List<GetQuote> quote = [];

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

getData() async{
  final response = await Quote.getQuote();

  setState(() {
    quote = response;
  });
}

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: backgroundColor,
      appBar: AppBar(
        elevation: 0.0,
        backgroundColor: backgroundColor,
        centerTitle: true,
        title: const Text(
          'Quote App',
          style: kAppBarTextStyle,
        ),
      ),
      body: Stack(
        alignment: Alignment.center,
        children: [
          PositionedWidget(
            top: 50,
            width: 250.0,
            height: 500,
            child: Container(
              decoration: BoxDecoration(
                color: smallContainerColor,
                borderRadius: BorderRadius.circular(10.0),
              ),
            ),
          ),
          PositionedWidget(
            top: 60,
            width: 300.0,
            height: 500,
            child: Container(
              decoration: BoxDecoration(
                color: mediumContainerColor,
                borderRadius: BorderRadius.circular(10.0),
              ),
            ),
          ),
          PositionedWidget(
          top: 70,
          width: 350.0,
          height: 500,
          child: ClipRRect(
            borderRadius: BorderRadius.circular(10.0),
            child: Container(
              decoration: const BoxDecoration(
                image: DecorationImage(
                  fit: BoxFit.cover,
                  image: AssetImage(kContainerImage),
                ),
              ),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children:const [
                  TextContainer(
                    text: ('Hello'),
                    style: kQuoteTextStyle,
                    padding: kQuotePadding,
                  ),
                  Align(
                    alignment: Alignment.bottomRight,
                    child: TextContainer(
                      text: 'Author\'s name',
                      style: kAuthornameTextStyle,
                      padding: kAuthornamePadding,
                    ),
                  )
                ],
              ),
            ),
          ),
            ),
        ],
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton:  FloatingActionButton.extended(
        backgroundColor: kFloatingActionButtonColor,
        onPressed: getData,
        label: const Text(
          'Next Quote',
          style: kFloatingActionTextStle,
        ),
      ),
    );
  }
}

解决方案

1. 完善API类的类型声明

给getQuote()指定明确返回类型,避免类型歧义:

class Quote {
  static Future<List<GetQuote>> getQuote() async {
    var client = http.Client();
    var uri = Uri.parse(apiUrl);
    var response = await client.get(
      uri,
      headers: {'X-RapidAPI-Key': apiKey, 'X-RapidAPI-Host': apiHost},
    );
    if(response.statusCode == 200){
      var json = response.body;
      return getQuoteFromJson(json);
    }
    else {
      throw Exception(response.reasonPhrase);
    }
  }
}

2. 修改UI代码动态展示数据

移除children前的const(因为内容是动态的),根据quote列表的状态展示数据:

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: backgroundColor,
    appBar: AppBar(
      elevation: 0.0,
      backgroundColor: backgroundColor,
      centerTitle: true,
      title: const Text(
        'Quote App',
        style: kAppBarTextStyle,
      ),
    ),
    body: Stack(
      alignment: Alignment.center,
      children: [
        // 保留原有定位容器代码
        PositionedWidget(
          top: 70,
          width: 350.0,
          height: 500,
          child: ClipRRect(
            borderRadius: BorderRadius.circular(10.0),
            child: Container(
              decoration: const BoxDecoration(
                image: DecorationImage(
                  fit: BoxFit.cover,
                  image: AssetImage(kContainerImage),
                ),
              ),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  TextContainer(
                    text: quote.isNotEmpty ? quote[0].quoteText : "加载中...",
                    style: kQuoteTextStyle,
                    padding: kQuotePadding,
                  ),
                  Align(
                    alignment: Alignment.bottomRight,
                    child: TextContainer(
                      text: quote.isNotEmpty ? quote[0].author : "加载中...",
                      style: kAuthornameTextStyle,
                      padding: kAuthornamePadding,
                    ),
                  )
                ],
              ),
            ),
          ),
        ),
      ],
    ),
    // 保留原有悬浮按钮代码
  );
}

3. 优化数据获取的类型安全

给getData()中的response指定类型,消除类型警告:

getData() async{
  final List<GetQuote> response = await Quote.getQuote();

  setState(() {
    quote = response;
  });
}

4. 可选:添加错误处理

在getData()中加入异常捕获,处理API请求失败的情况:

getData() async{
  try{
    final List<GetQuote> response = await Quote.getQuote();
    setState(() {
      quote = response;
    });
  } catch(e){
    if(mounted){
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("获取语录失败:$e"))
      );
    }
  }
}

内容的提问来源于stack exchange,提问作者Martins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 22:13:21