我可以覆盖 MaterialBanner 小部件来更改其高度吗?

2024-02-02

我正在处理ScaffoldMessenger.of(context).showMaterialBanner方法,它需要一个 MaterialBanner 小部件作为参数。

Goal

就我而言,我需要放置一个空的 MaterialBanner 小部件,但具有自定义高度(小于默认值)。

简而言之,重写原始的 MaterialBanner 构建方法。

我尝试过的

所以我想我必须扩展一个 StatefulWidget 来实现 MaterialBanner:

class MiniBanner extends StatefulWidget implements MaterialBanner {
  const MiniBanner({Key? key}) : super(key: key);

  @override
  List<Widget> get actions => [const SizedBox()];

  @override
  Animation<double>? get animation => null;

  @override
  Color? get backgroundColor => Colors.amber;

  @override
  Widget get content => const SizedBox();

  @override
  TextStyle? get contentTextStyle => null;

  @override
  double? get elevation => 0;

  @override
  bool get forceActionsBelow => false;

  @override
  Widget? get leading => null;

  @override
  EdgeInsetsGeometry? get leadingPadding => EdgeInsets.zero;

  @override
  VoidCallback? get onVisible => null;

  @override
  OverflowBarAlignment get overflowAlignment => OverflowBarAlignment.end;

  @override
  EdgeInsetsGeometry? get padding => EdgeInsets.zero;

  @override
  MaterialBanner withAnimation(Animation<double> newAnimation, {Key? fallbackKey}) {
    return MaterialBanner(
      key: key ?? fallbackKey,
      content: content,
      contentTextStyle: contentTextStyle,
      actions: actions,
      elevation: elevation,
      leading: leading,
      backgroundColor: backgroundColor,
      padding: padding,
      leadingPadding: leadingPadding,
      forceActionsBelow: forceActionsBelow,
      overflowAlignment: overflowAlignment,
      animation: newAnimation,
      onVisible: onVisible,
    );
  }

  @override
  State<MiniBanner> createState() => _MiniBannerState();
}

class _MiniBannerState extends State<MiniBanner> {
  @override
  Widget build(BuildContext context) {
    // I want the code to go here to build a smaller MaterialBanner
    return Container(
      color: widget.backgroundColor,
      height: 10,
    );
  }
}

但我的代码继续使用原始的 MaterialBanner 方法。 也许我缺少一些有关扩展有状态小部件的知识。


Solved

主要问题是“withAnimation”方法的返回类型。它必须与您的自定义小部件类型相同。 所以:

class MiniBanner extends StatefulWidget implements MaterialBanner {
  const MiniBanner({
    Key key,
    this.content = const SizedBox(),
    this.contentTextStyle,
    this.actions = const [SizedBox()],
    this.elevation = 0,
    this.leading,
    this.backgroundColor = Colors.red, //custom default color
    this.padding = EdgeInsets.zero,
    this.leadingPadding = EdgeInsets.zero,
    this.forceActionsBelow = false,
    this.overflowAlignment = OverflowBarAlignment.end,
    this.animation,
    this.onVisible,
  })  : assert(elevation == null || elevation >= 0.0),
        assert(content != null),
        assert(actions != null),
        assert(forceActionsBelow != null),
        super(key: key);

  @override
  final List<Widget> actions;

  @override
  final Animation<double> animation;

  @override
  final Color backgroundColor;

  @override
  final Widget content;

  @override
  final TextStyle contentTextStyle;

  @override
  final double elevation;

  @override
  final bool forceActionsBelow;

  @override
  final Widget leading;

  @override
  final EdgeInsetsGeometry leadingPadding;

  @override
  final VoidCallback onVisible;

  @override
  final OverflowBarAlignment overflowAlignment;

  @override
  final EdgeInsetsGeometry padding;

  @override
  MiniBanner withAnimation(Animation<double> newAnimation, {Key fallbackKey}) {
    return MiniBanner(
      key: key ?? fallbackKey,
      content: content,
      contentTextStyle: contentTextStyle,
      actions: actions,
      elevation: elevation,
      leading: leading,
      backgroundColor: backgroundColor,
      padding: padding,
      leadingPadding: leadingPadding,
      forceActionsBelow: forceActionsBelow,
      overflowAlignment: overflowAlignment,
      animation: newAnimation,
      onVisible: onVisible,
    );
  }

  @override
  State<MiniBanner> createState() => MiniBannerState();
}

class MiniBannerState extends State<MiniBanner> {
  @override
  Widget build(BuildContext context) {
    // Now our MiniBanner correctly build this method
    return Container(
      color: widget.backgroundColor,
      height: 10,
    );
  }
}

重要的提示

此代码不是空声音安全,因此如果您的 Flutter 应用程序启用了空声音安全,则必须更改一些语法,例如添加 ?在可为空的属性之后等等。

UPDATE

如果您想真正模拟原始 MaterialBanner 的所有动画,您必须复制几乎整个原始“构建”方法。 然后,要自定义您的小部件,您只需编辑materialBanner变量,示例:

// other parts of code copied from original build method above

Widget materialBanner = Container(
  color: widget.backgroundColor,
  height: 10,
);

// other parts of code copied from original build method below
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我可以覆盖 MaterialBanner 小部件来更改其高度吗? 的相关文章

随机推荐