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

Flutter TabController无法获取API返回的视频列表长度如何解决

问题根源

_getAllVideos 是异步函数,initState 调用它时不会等待异步请求完成,会直接执行后续的 TabController 初始化逻辑,此时接口还未返回数据,_videoList 还是初始的空数组,因此拿到的长度为 0。

解决步骤

按以下方式修改代码即可正常获取长度:

  1. 初始化阶段先创建临时 TabController,等接口返回数据后再更新控制器
  2. 注意销毁旧控制器避免内存泄漏
  3. 增加加载状态判断避免渲染不匹配报错

1. 修改initState逻辑

late TabController _tabController;
bool isLoading = true;
List<Video> _videoList = [];

@override
void initState() {
  super.initState();
  // 先初始化临时控制器,长度填0即可
  _tabController = TabController(length: 0, vsync: this);
  _getAllVideos();
}

2. 修改_getAllVideos逻辑,拿到数据后更新TabController

_getAllVideos() async {
    var categories = await _videoService.getVideos();
    var _list = json.decode(categories.body);
    List<Video> results = [];
    _list['data'].forEach((data) {
      var model = Video();
      model.id = data["id"];
      model.videoUrl = data["videourl"];
      model.likes = data["likes"];
      model.profileImg = data["profileImg"];
      results.add(model);
    });
      if(mounted){
        // 先销毁旧的控制器
        _tabController.dispose();
        // 用最新的视频列表长度创建新控制器
        _tabController = TabController(length: results.length, vsync: this);
        setState(() {
          _videoList = results;
          isLoading = false;
        });
        print(_videoList.length); // 此时可拿到正确长度
      }
  }

3. 给getBody增加加载状态判断,避免渲染报错

Widget getBody() {
  // 数据加载完成前显示加载动画
  if (isLoading) {
    return const Center(child: CircularProgressIndicator());
  }
  var size = MediaQuery.of(context).size;
  return RotatedBox(
    quarterTurns: 1,
    child: TabBarView(
      physics: const BouncingScrollPhysics(),
      controller: _tabController,
      children: List.generate(_videoList.length, (index) {
          return VideoPlayerItem(
            videoUrl: _videoList[index].videoUrl!.toString(),
            profileImg: _videoList[index].albumImg!,
            likes: _videoList[index].likes.toString(),
          );
        },),
    ),
  );
}

4. 页面销毁时释放控制器

@override
void dispose() {
  _tabController.dispose();
  super.dispose();
}

注意:如果配套使用了TabBar组件,TabBar的子元素数量也要和_videoList长度保持一致,在setState更新数据后同步渲染即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 23:09:04