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

Flutter:自定义AppBar进度条重叠问题及未渲染Widget尺寸获取优化

优化带进度条的自定义AppBar实现(避免尺寸适配问题)

你当前通过GlobalKey+PostFrameCallback手动计算尺寸的方式确实能解决问题,但利用Flutter原生布局系统可以更简洁地实现需求,完全避免手动计算带来的适配风险:


核心优化思路

放弃Stack层叠布局,改用Column线性排列导航栏与进度条,让Flutter自动处理不同屏幕下的尺寸适配,无需手动计算组件高度。

优化后的完整代码

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

class ProgressHeader extends HookWidget implements PreferredSizeWidget {
  ProgressHeader({
    super.key,
    required this.title,
    required this.begin,
    required this.end,
  });

  final String title;
  final double begin;
  final double end;

  @override
  Size get preferredSize => Size.fromHeight(
        MediaQuery.of(context).padding.top + kToolbarHeight + 6,
      );

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: const Color.fromRGBO(170, 217, 149, 1),
        borderRadius: const BorderRadius.vertical(
          bottom: Radius.circular(20),
        ),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(.16),
            blurRadius: 4,
            offset: const Offset(0, 3),
          ),
          BoxShadow(
            color: Colors.black.withOpacity(.16),
            blurRadius: 6,
            offset: const Offset(0, 6),
          )
        ],
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          // 黑色导航栏区域
          Container(
            decoration: const BoxDecoration(
              color: Colors.black,
              borderRadius: BorderRadius.vertical(bottom: Radius.circular(25)),
            ),
            child: Padding(
              padding: const EdgeInsets.only(
                left: 16.0,
                right: 16.0,
                bottom: 8,
              ),
              child: SafeArea(
                bottom: false,
                child: Row(
                  children: [
                    IconButton(
                      iconSize: 18,
                      icon: const Icon(Icons.arrow_back, color: Colors.white),
                      onPressed: () {
                        Navigator.pop(context);
                      },
                    ),
                    const SizedBox(width: 16),
                    Text(
                      title,
                      style: Theme.of(context)
                          .textTheme
                          .bodyLarge!
                          .copyWith(color: Colors.white),
                    ),
                  ],
                ),
              ),
            ),
          ),
          // 进度条区域(固定高度6px)
          Container(
            height: 6,
            decoration: const BoxDecoration(
              color: Color.fromRGBO(127, 181, 103, 1),
              borderRadius: BorderRadius.only(
                bottomLeft: Radius.circular(20),
              ),
            ),
            // 可选:添加进度动画
            child: Align(
              alignment: Alignment.centerLeft,
              child: AnimatedContainer(
                duration: const Duration(milliseconds: 300),
                width: MediaQuery.of(context).size.width * end,
                decoration: const BoxDecoration(
                  borderRadius: BorderRadius.only(
                    bottomLeft: Radius.circular(20),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

优化点说明

  1. 布局结构简化:用Column替代Stack,导航栏与进度条自然垂直排列,彻底避免层叠导致的重叠问题
  2. 动态高度适配:PreferredSize通过MediaQuery获取顶部安全区高度,结合系统默认工具栏高度kToolbarHeight+进度条高度,自动适配不同设备
  3. 移除冗余代码:不再需要自定义useGetSize Hook和GlobalKey,代码更简洁易维护
  4. 原生动画支持:用AnimatedContainer实现进度条的平滑过渡动画,符合你的预期效果需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:11:01