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), ), ), ), ), ), ], ), ); } }
优化点说明
- 布局结构简化:用
Column替代Stack,导航栏与进度条自然垂直排列,彻底避免层叠导致的重叠问题 - 动态高度适配:
PreferredSize通过MediaQuery获取顶部安全区高度,结合系统默认工具栏高度kToolbarHeight+进度条高度,自动适配不同设备 - 移除冗余代码:不再需要自定义
useGetSizeHook和GlobalKey,代码更简洁易维护 - 原生动画支持:用
AnimatedContainer实现进度条的平滑过渡动画,符合你的预期效果需求
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

