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

Flutter中解决API自动触发及搜索无法刷新请求问题

问题解决方案

核心问题分析

  1. 启动时自动调用API:因为你在initState里直接初始化了futureVideo = fetchVideo(),此时输入框为空,导致空请求。
  2. 点击搜索不刷新结果:只修改了isVisible,但没有重新触发API请求并更新futureVideo,所以FutureBuilder不会重新构建。

具体修改步骤

1. 重构API请求函数,传入搜索关键词

把fetchVideo改成接收参数的形式,避免依赖全局控制器,同时增加空输入判断:

Future<Video> fetchVideo(String query) async {
  if (query.trim().isEmpty) {
    throw Exception('请输入搜索关键词');
  }
  final response = await http.get(Uri.parse(
      'https://youtube.googleapis.com/youtube/v3/search?part=snippet&channelType=any&eventType=completed&maxResults=3&q=$query&safeSearch=none&type=video&videoLicense=any&videoSyndicated=any&videoType=any&key=[my api key]'));

  if (response.statusCode == 200) {
    return Video.fromJson(jsonDecode(response.body));
  } else {
    throw Exception('加载视频失败');
  }
}

2. 修正State类的状态管理

  • 将searchController移到State类内部(避免全局变量导致的状态混乱)
  • 把futureVideo改为可空类型,初始不赋值(避免启动时自动请求)
  • 移除initState里的futureVideo初始化代码

修改后的State类:

class _AddPageState extends State<AddPage> {
  final TextEditingController searchController = TextEditingController();
  Future<Video>? futureVideo;
  bool isVisible = false;

  @override
  Widget build(BuildContext context) {
    // ...原build代码
  }
}

3. 修复搜索按钮的点击逻辑

在按钮的onPressed里,触发API请求并更新futureVideo,同时处理空输入:

onPressed: () {
  setState(() {
    final query = searchController.text.trim();
    if (query.isNotEmpty) {
      futureVideo = fetchVideo(query);
      isVisible = true;
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('请输入搜索内容')),
      );
      isVisible = false;
    }
  });
},

4. 增强Video解析的安全性

避免API返回空结果时崩溃,在fromJson里增加空判断:

factory Video.fromJson(Map<String, dynamic> map) {
  if (map['items'] == null || map['items'].isEmpty) {
    throw Exception('未找到相关视频');
  }
  final item = map['items'][0];
  return Video(
    title0: item['snippet']['title'],
    author0: item['snippet']['channelTitle'],
    thumbnail0: item['snippet']['thumbnails']['medium']['url'],
  );
}

5. 优化结果展示逻辑(可选)

如果使用FutureBuilder展示结果,其实可以去掉isVisible,直接根据futureVideo是否为null控制显示:

// 替换原来的Visibility组件
if (futureVideo != null) {
  return FutureBuilder<Video>(
    future: futureVideo,
    builder: (context, snapshot) {
      if (snapshot.hasData) {
        return Column(
          children: [
            Text(snapshot.data!.title0),
            Text(snapshot.data!.author0),
            Image.network(snapshot.data!.thumbnail0),
          ],
        );
      } else if (snapshot.hasError) {
        return Text('${snapshot.error}');
      }
      return const CircularProgressIndicator();
    },
  );
} else {
  return const SizedBox.shrink(); // 初始状态不显示任何内容
}

关键说明

  • 让API请求函数接收参数,而不是依赖外部控制器,使逻辑更清晰、可复用
  • 通过setState更新futureVideo,触发FutureBuilder重新构建,实现结果刷新
  • 增加空输入和空结果判断,避免无效请求和崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:01:07