如何创建具有动态值的可重用 Flutter 应用栏

How to create reusable Flutter app bar with dynamic value

我正在尝试创建一个具有动态大小的可重用应用栏。我正在使用动态值来调整应用程序中图标、填充、文本字体大小等的大小,并希望对应用程序栏大小执行相同的操作。下面的应用程序条形码动态工作,并为我提供了我想要使用 MediaQuery 的行为。

class SamplePage extends StatelessWidget {
  const SamplePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final screenHeight = MediaQuery.of(context).size.height;
    return Scaffold(
      appBar: AppBar(
        actions: const [
          BrandPopUpMenu(),
        ],
        automaticallyImplyLeading: true,
        centerTitle: true,
        title: const AppBarText(
          pageName: PageName.nutrition,
        ),
        toolbarHeight: screenHeight / 15.07,
      ),
      drawer: const SideSheet(),
      body: Container(),
    );
  }
}

当我尝试从上面的代码创建可重复使用的应用程序栏时,我 运行 遇到了麻烦。

class SamplePage extends StatelessWidget {
  const SamplePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final screenHeight = MediaQuery.of(context).size.height;
    return Scaffold(
      appBar: SamplePageDynamicAppBar(screenHeight: screenHeight),
      drawer: const SideSheet(),
      body: Container(),
    );
  }
}

下面的代码仅适用于硬编码的首选大小,我不确定如何继续使用 toolBarHeight 中的动态值而不是覆盖中的首选大小。

class SamplePageDynamicAppBar extends StatelessWidget
    implements PreferredSizeWidget {
  const SamplePageDynamicAppBar({
    Key? key,
    required this.screenHeight,
  }) : super(key: key);

  final double screenHeight;

  @override
  Size get preferredSize => const Size.fromHeight(56.0);
  
  @override
  Widget build(BuildContext context) {
    return AppBar(
      actions: const [
        BrandPopUpMenu(),
      ],
      automaticallyImplyLeading: true,
      centerTitle: true,
      title: const AppBarText(
        pageName: PageName.nutrition,
      ),
      toolbarHeight: screenHeight / 15.07,
    );
  }
}

任何帮助将不胜感激。谢谢

当您在 scaffold 中引用它时,请尝试使用 PreferredSize 小部件包装您的自定义 AppBar,如下所示,而不是通过您的首选高度,而是将其声明为PreferredSize 小部件:

class SamplePage extends StatelessWidget {
  const SamplePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final screenHeight = MediaQuery.of(context).size.height;
    return PreferredSize(
      preferredSize: Size.fromHeight(screenHeight / 15.07),
      child: Scaffold(
        appBar: SamplePageDynamicAppBar(),
        drawer: const SideSheet(),
        body: Container(),
      ),
    );
  }
}

由于您所做的只是覆盖 AppBar 的 toolbarHeight 属性,所以看看这是否有效。它扩展了 AppBar 而不是创建一个新的小部件。 https://dartpad.dev/?id=d15b4d91168e13b89e86267da4311683

class SamplePageDynamicAppBar extends AppBar {
  SamplePageDynamicAppBar({Key? key, required double screenHeight}) :
    super(
      actions: const [
        BrandPopUpMenu(),
      ],
      automaticallyImplyLeading: true,
      centerTitle: true,
      title: const AppBarText(
        pageName: PageName.nutrition,
      ),
      toolbarHeight: screenHeight / 15.07,
    );
}

或者,您可以通过更改 perferredSize getter 的实现来使用您编写的代码。 https://dartpad.dev/?id=758db4b7a7b2908b166a6a29d766045d

class SamplePageDynamicAppBar extends StatelessWidget implements PreferredSizeWidget {
  const SamplePageDynamicAppBar({
    Key? key,
    required double screenHeight,
  }) : 
    toolbarHeight = screenHeight / 15.07,    
    super(key: key);

  final double toolbarHeight;

  @override
  Size get preferredSize => Size.fromHeight(toolbarHeight);
 
  @override
  Widget build(BuildContext context) {
    return AppBar(
      actions: const [
        BrandPopUpMenu(),
      ],
      automaticallyImplyLeading: true,
      centerTitle: true,
      title: const AppBarText(
        pageName: PageName.nutrition,
      ),
      toolbarHeight: toolbarHeight,
    );
  }
}