Flutter自定义ReusableAppbar报错:无法赋值给PreferredSizeWidget参数
解决Flutter自定义AppBar的PreferredSizeWidget类型错误
问题原因
Scaffold的appBar参数要求传入PreferredSizeWidget类型组件,而你的ReusableAppbar仅继承了StatelessWidget,类型不匹配导致报错。
解决方案:让自定义AppBar实现PreferredSizeWidget接口
直接修改ReusableAppbar类,使其实现PreferredSizeWidget接口并指定尺寸,是最优雅的复用方案。
修改后的ReusableAppbar代码
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'button/reusable_back_button.dart'; class ReusableAppbar extends StatelessWidget implements PreferredSizeWidget { final Function backButtonOnTap; final String appbarTitleText; final Color appbarBackgroundColor; final Widget additionalWidget; final Widget additionalWidget2; final double height; const ReusableAppbar({ required this.backButtonOnTap, required this.appbarTitleText, this.appbarBackgroundColor = Colors.white, this.height = 60, this.additionalWidget = const SizedBox.shrink(), this.additionalWidget2 = const SizedBox.shrink(), Key? key}) : super(key: key); // 实现PreferredSizeWidget的核心属性 @override Size get preferredSize => Size.fromHeight(height); @override Widget build(BuildContext context) { return AppBar( iconTheme: IconThemeData(color: appbarBackgroundColor), automaticallyImplyLeading: false, centerTitle: false, backgroundColor: personalBackGround, toolbarHeight: height, title: Column( children: [ Padding( padding: EdgeInsets.symmetric(horizontal: 13), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Row( children: [ GestureDetector( // 修复:使用传入的backButtonOnTap替代硬编码逻辑 onTap: () => backButtonOnTap(), child: ReusableBackButton(color: primaryColor), ), Text( appbarTitleText, style: primaryColor600Style.copyWith( fontSize: fontSize16, ), ).tr(), ], ), ), additionalWidget, ], ), ), additionalWidget2, ], ), ); } }
额外提示
- 原代码中
backButtonOnTap参数未被实际使用,已修改为在点击事件中调用,符合参数设计预期。 - 代码中
personalBackGround、primaryColor等自定义变量需确保已在项目中定义,否则会出现新的错误。 - 若未集成国际化包,可直接删除
.tr()方法。
备选方案:用PreferredSize包裹自定义AppBar(无需修改原类)
如果不想修改ReusableAppbar类,也可以在使用时用PreferredSize组件临时包裹:
Widget build(BuildContext context) { return Scaffold( appBar: PreferredSize( preferredSize: Size.fromHeight(60), // 指定AppBar高度 child: ReusableAppbar( backButtonOnTap: (){ Navigator.pop(context); }, appbarTitleText: 'Try appbar', ), ), ); }
内容的提问来源于stack exchange,提问作者Kim San
相关产品推荐
相关产品推荐

