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

如何在Flutter中使用PreferredSize实现响应式高度的AppBar?

如何用PreferredSize实现响应式高度的AppBar

核心实现思路

要让AppBar高度在不同设备上自适应,关键是让PreferredSize的高度基于设备屏幕尺寸动态计算,而非固定数值。以下两种方式可实现需求:


方法1:基于MediaQuery动态计算

直接利用MediaQuery获取屏幕尺寸的比例值设置高度,确保在不同设备上保持一致的视觉占比:

class ResponsiveAppBar extends StatelessWidget implements PreferredSizeWidget {
  @override
  Size get preferredSize => Size.fromHeight(MediaQuery.of(context).size.height * 0.2); // 占屏幕高度20%

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: preferredSize.height,
      child: Stack(
        clipBehavior: Clip.none,
        children: [
          Image.asset('assets/topBackground.png', fit: BoxFit.cover, height: double.infinity),
          Positioned(
            left: MediaQuery.of(context).size.width * 0.08, // 左间距占屏幕宽度8%
            top: MediaQuery.of(context).size.height * 0.025,
            child: SizedBox(
              width: MediaQuery.of(context).size.width * 0.84,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Icon(Icons.menu, color: Colors.white),
                  CircleAvatar(child: Image.asset("assets/Emmanuel_Jerry.png")),
                ],
              ),
            ),
          ),
          Positioned(
            top: MediaQuery.of(context).size.height * 0.06,
            left: MediaQuery.of(context).size.width * 0.1,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                SizedBox(height: MediaQuery.of(context).size.height * 0.02),
                Text(
                  "Emmanuel Jerry",
                  style: GoogleFonts.poppins(
                    textStyle: TextStyle(color: Colors.white, fontSize: MediaQuery.of(context).size.width * 0.053),
                  ),
                ),
                Text(
                  "HI Welcome back",
                  style: GoogleFonts.poppins(
                    textStyle: TextStyle(color: Colors.white, fontSize: MediaQuery.of(context).size.width * 0.037),
                  ),
                )
              ],
            ),
          ),
        ],
      ),
    );
  }
}

// 使用方式
Scaffold(
  appBar: ResponsiveAppBar(),
  // ...其他页面内容
)

方法2:使用适配库(如flutter_screenutil)

若已在用flutter_screenutil做屏幕适配,确保初始化正确后,用相对单位设置高度和位置即可:

  1. 先在main函数初始化适配:
void main() {
  runApp(
    ScreenUtilInit(
      designSize: Size(375, 812), // 对应设计稿尺寸
      minTextAdapt: true,
      splitScreenMode: true,
      child: MyApp(),
    ),
  );
}
  1. 自定义响应式AppBar:
class ResponsiveAppBar extends StatelessWidget implements PreferredSizeWidget {
  @override
  Size get preferredSize => Size.fromHeight(155.h); // 基于设计稿的相对高度

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: preferredSize.height,
      child: Stack(
        clipBehavior: Clip.none,
        children: [
          Image.asset('assets/topBackground.png', fit: BoxFit.cover, height: double.infinity),
          Positioned(
            left: 8.w,
            top: 20.h,
            child: SizedBox(
              width: MediaQuery.of(context).size.width - 16.w,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Icon(Icons.menu, color: Colors.white),
                  CircleAvatar(child: Image.asset("assets/Emmanuel_Jerry.png")),
                ],
              ),
            ),
          ),
          Positioned(
            top: 50.h,
            left: 10.w,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                SizedBox(height: 2.h),
                Text(
                  "Emmanuel Jerry",
                  style: GoogleFonts.poppins(textStyle: TextStyle(color: Colors.white, fontSize: 20.sp)),
                ),
                Text(
                  "HI Welcome back",
                  style: GoogleFonts.poppins(textStyle: TextStyle(color: Colors.white, fontSize: 14.sp)),
                )
              ],
            ),
          ),
        ],
      ),
    );
  }
}

注意事项

  • 避免直接在默认AppBar的bottom属性中嵌套大高度PreferredSize,否则会和默认AppBar的kToolbarHeight叠加,导致整体高度超出预期。直接自定义PreferredSizeWidget替换默认AppBar更可控。
  • 所有元素的位置、尺寸都需使用相对单位(MediaQuery比例或适配库单位),禁止使用固定像素值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 09:40:17