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

如何在FutureBuilder完成数据加载前优先加载bottom navigation bar等静态元素

实现FutureBuilder加载前优先渲染底部导航栏的方案

问题根源

你现有代码中将包含bottomNavigationBar、悬浮按钮的完整Scaffold放在了FutureBuilder的请求成功分支中,因此导航栏等静态元素必须等接口返回后才会渲染,不符合预期。

实现思路

将所有静态不变的元素(底部导航栏、悬浮按钮、悬浮按钮位置配置等)放在外层Scaffold,仅把需要动态加载的内容区域交给FutureBuilder控制,进入页面时静态元素会第一时间渲染,只有中间内容区域会根据请求状态显示加载动画/错误提示/实际内容。

修改后代码

import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:package/constants/AppConstants.dart';
import 'package:package/util/HttpActions.dart';

import 'BottomAppBar.dart';
import 'FAB.dart';

class HomePage extends StatefulWidget {
  final String jwt;

  const HomePage(this.jwt);

  @override
  _HomePage createState() => _HomePage();

  factory HomePage.fromBase64(String jwt) => HomePage(jwt);
}

class _HomePage extends State<HomePage> {
  late final String jwt;
  // 提前定义请求Future,避免每次build重复发起请求
  late Future<http.Response> _requestFuture;

  @override
  void initState() {
    super.initState();
    jwt = widget.jwt;
    final uri = Uri.http(
        AppConstants.BASE_URL,
        AppConstants.SOME_URL,
        {'email': 'some.mail@gmail.com'}); // TODO change to proper link
    // 初始化时就发起请求
    _requestFuture = http.get(
      uri,
      headers: {
        HttpHeaders.contentTypeHeader:
        HttpActions.APPLICATION_JSON_HEADER,
        HttpHeaders.authorizationHeader: jwt
      },
    );
  }

  @override
  Widget build(BuildContext context) => Scaffold(
    backgroundColor: const Color(0xFEF9F9FC),
    // 静态元素直接放在外层Scaffold,进入页面立刻渲染
    floatingActionButtonLocation:
    FloatingActionButtonLocation.centerDocked,
    floatingActionButton: buildFAB(),
    bottomNavigationBar: BuildBottomAppBar(),
    // 仅body部分交给FutureBuilder动态控制
    body: Center(
      child: FutureBuilder(
          future: _requestFuture,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              // 这里直接返回请求成功后你要展示的内容组件,不需要再套Scaffold
              return 你请求成功后的页面内容组件;
            } else if (snapshot.hasError) {
              return const Text("An error occurred");
            } else {
              return const CircularProgressIndicator();
            }
          }
      ),
    ),
  );
}

注意事项

  • 不要直接在FutureBuilder的future参数中创建请求实例,否则页面每次重绘都会重复发起接口请求,提前在initState中初始化请求即可避免该问题
  • 成功分支无需再嵌套Scaffold,直接返回你原本要放在body区域的业务内容组件即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 13:12:02