如何创建自定义 AppBar 小部件?

Posted

技术标签:

【中文标题】如何创建自定义 AppBar 小部件?【英文标题】:How to create a custom AppBar widget? 【发布时间】:2019-04-17 01:17:18 【问题描述】:

我是新来的颤振。我正在尝试创建自定义 appbar 小部件并在页面中导入小部件。

但我无法创建小部件。

import 'package:flutter/material.dart';
 
 class AppBar extends StatelessWidget
  @override
  Widget build(BuildContext context)
return AppBar(
  title: Text('Ordering'),
  actions: <Widget>[
    IconButton(
      onPressed: _incrementCounter,
      icon: Icon(Icons.add),
    ),
    BadgeIconButton(
      itemCount: _counter,
      badgeColor: Color.fromRGBO(37, 134, 16, 1.0),
      badgeTextColor: Colors.white,
      icon: Icon(Icons.shopping_cart, size: 30.0,),
      onPressed: () 
    ),
  ],
);

'

【问题讨论】:

【参考方案1】:
import 'package:flutter/material.dart';

class CustomAppBar extends StatefulWidget implements PreferredSizeWidget 
    CustomAppBar(Key key) : preferredSize = Size.fromHeight(kToolbarHeight), super(key: key);

    @override
    final Size preferredSize; // default is 56.0

    @override
    _CustomAppBarState createState() => _CustomAppBarState();


class _CustomAppBarState extends State<CustomAppBar>

    @override
    Widget build(BuildContext context) 
        return AppBar( title: Text("Sample App Bar") );
    

希望这会有所帮助

【讨论】:

另外,material.dart 中有 'kToolbarHeight' const,所以最好使用preferredSize = Size.fromHeight(kToolbarHeight) 谢谢!如果您希望将您的 CustomAppBar 放在单独的文件中(推荐),则此方法有效。 这应该是公认的答案。我要补充一点,这里没有必要创建 StatefulWidget。您可以将其设为 StatelessWidget。也可以像final Size preferredSize = Size.fromHeight(kToolbarHeight)一样直接设置preferredSize属性来简化构造函数。【参考方案2】:
class AppBars extends AppBar 
  AppBars():super(
    iconTheme: IconThemeData(
      color: Colors.black, //change your color here
    ),
    backgroundColor: Colors.white,
    title: Text(
      "this is app bar",
      style: TextStyle(color: Color(Constant.colorBlack)),
    ),
    elevation: 0.0,
    automaticallyImplyLeading: false,
    actions: <Widget>[
      IconButton(
        icon: Icon(Icons.notifications),
        onPressed: () => null,
      ),
      IconButton(
        icon: Icon(Icons.person),
        onPressed: () => null,
      ),
    ],
  );

【讨论】:

【参考方案3】:
Widget build(BuildContext context) 
  return new Scaffold(
    appBar: setAppBar(),
    body: new Container() // add rest of the UI
  );

Widget setAppBar() 
  return new AppBar(
  //backgroundColor: Colors.blue,
  //automaticallyImplyLeading: true
  elevation: 0.0, // for elevation
  titleSpacing: 0.0, // if you want remove title spacing with back button
  title:  UtilCommonWidget.addTextMedium('About US', Colors.white, 20.0, 1),
  actions: <Widget>[
    addAppBarActionWidgetProfile(icon, 30.0, 30.0, 15.0) // add your custom action widget
  ],//Action icon search as search icon, notification icon
  leading: new Material( //Custom leading icon, such as back icon or other icon
    color: Colors.transparent,
    child: new InkWell(
      onTap: () 
        Navigator.of(context).pop();
      ,
      splashColor: UniQueryColors.colorGradientEnd.withOpacity(.5),
      child: new Container(
          padding: const EdgeInsets.fromLTRB(12.0, 16.0, 16.0, 16.0),
          child: UtilCommonWidget.addImage(Constant.iconBack, 19.0, 10.0))
      ),
  )
 );

【讨论】:

我正在尝试在单独的 dart 文件中创建 appbar 小部件并导入。 您可以使用 setAppBar 函数创建一个小部件。然后将其添加到您的主用户界面 感谢您的支持,但只有在同一文件中创建 appbar 小部件时,您的回答才有效。 按照此说明如何创建自定义小部件并使用此代码创建自定义应用栏。 youtube.com/watch?v=W1pNjxmNHNQ "参数类型 'AppBarWidget' 不能分配给参数类型 'PreferredSizeWidget'。"出现上述错误【参考方案4】:

AppBar 实现了 PreferredSizeWidget 类,这意味着 AppBar 必须具有首选大小。

preferredSize 变量被覆盖,因为它是从 PreferredSizeWidget 实现的,在这里您可以设置您希望的高度。

class CustomAppBar extends StatefulWidget implements PreferredSizeWidget 
  CustomAppBar(Key key) : preferredSize = Size.fromHeight(60.0), super(key: key);

  @override
  final Size preferredSize;

  @override
  _CustomAppBarState createState() => _CustomAppBarState();


class _CustomAppBarState extends State<CustomAppBar>

  @override
  Widget build(BuildContext context) 
    return AppBar(
      title: Text('App Bar'),
      actions: <Widget>[
        IconButton(
          icon: Icon(Icons.add, color: Colors.white,),
        ),
      ],
    );
  

并像这样使用

class _MyHomePageState extends State<MyHomePage> 
  
  @override
  Widget build(BuildContext context) 
    return new Scaffold(
      appBar: CustomAppBar()
    );
  

【讨论】:

【参考方案5】:

我用我的自定义小部件扩展了 AppBar。 然后将我的参数传递给超类

class CustomAppBar extends AppBar 
  CustomAppBar()
      : super(
          title: Text('MyApp'),
          actions: [
            IconButton(icon: Icon(Icons.search), onPressed: () ),
          ],
        );

【讨论】:

【参考方案6】:

编辑 riftninja 的回答:

import 'package:flutter/material.dart';

class CustomAppBar extends StatefulWidget implements PreferredSizeWidget 
  CustomAppBar(Key key, double height) : preferredSize = 
       Size.fromHeight(height), super(key: key);

  @override
  //final Size preferredSize; // This didnot work for me.
  Size get preferredSize => preferredSize; //This should work.

  @override
  _CustomAppBarState createState() => _CustomAppBarState();
  

 class _CustomAppBarState extends State<CustomAppBar>

  @override
  Widget build(BuildContext context) 
    return AppBar( title: Text("Sample App Bar") );
  
  

这也适用于无状态小部件。

【讨论】:

【参考方案7】:

widget_appbar.dart

class WidgetAppBar extends StatelessWidget implements PreferredSizeWidget 
  final Color? backgroundColor;
  final Color? textIconColor;
  final String? icon;
  final String? title;
  final double? height;
  final List<Widget>? menuItem;
  final bool hideBack;

  WidgetAppBar(
    this.backgroundColor = whiteColor,
    this.textIconColor = headingColor,
    this.icon,
    this.title = '',
    this.menuItem,
    this.height: kToolbarHeight,
    this.hideBack = false,
  );

  @override
  Size get preferredSize => Size.fromHeight(height!);

  @override
  Widget build(BuildContext context) 
    return AppBar(
      actions: menuItem,
      toolbarHeight: preferredSize.height,
      iconTheme: IconThemeData(
        color: textIconColor,
      ),
      leading: hideBack
          ? Container()
          : icon == null
              ? BackButton()
              : IconButton(
                  icon: Image.asset(
                    icon!,
                    height: 18,
                    width: 18,
                  ),
                  onPressed: () 
                    Navigator.pop(context, true);
                  ,
                ),
      title: Text(
        title!,
        style: TextStyle(
          fontSize: 20,
          fontWeight: FontWeight.bold,
          color: textIconColor,
        ),
      ),
      backgroundColor: backgroundColor,
      centerTitle: true,
    );
  

如何使用?

@override
Widget build(BuildContext context) 
  return Scaffold(
    appBar: WidgetAppBar(
      icon: ic_back_black,
      title: 'Toolbar Title',
    ),
    body: SafeArea(
      child: Container(),
    ),
  );

【讨论】:

【参考方案8】:

屏幕截图(Null Safe):


完整代码:

创建这个类。

class CustomAppBar extends StatelessWidget implements PreferredSizeWidget 
  final Widget child;
  final double height;

  CustomAppBar(
    required this.child,
    this.height = kToolbarHeight,
  );

  @override
  Size get preferredSize => Size.fromHeight(height);

  @override
  Widget build(BuildContext context) 
    return Container(
      height: preferredSize.height,
      color: Colors.red,
      child: child,
    );
  

用法:

Scaffold(
  appBar: CustomAppBar(
    height: 100,
    child: Column(
      children: [
        FlutterLogo(size: 56),
        SizedBox(height: 8),
        Text('Flutter'),
      ],
    ),
  ),
)

【讨论】:

以上是关于如何创建自定义 AppBar 小部件?的主要内容,如果未能解决你的问题,请参考以下文章

带有自定义按钮的导航抽屉

[flutter专题]详解AppBar小部件

Flutter 自定义 AppBar 动作并将 Appbar 和 Body 一起传递给父级?

Flutter Appbar 标题灰色背景显示

如何开始使用自定义 GUI 小部件

如何创建自定义颤振 sdk 小部件,重建颤振和使用新的小部件