Flutter入门: Scaffold 详解

Auth:老猿𝕏𝕏       Date:2024/04/26       Cat:编程       Word:共9616字

  1. 前言
  2. 属性
    1. 属性一览
    2. appBar: 页面上方导航条
      1. 实现
      2. AppBar 示例
      3. Tab 示例
      4. TabBar 示例
      5. CupertinoTabBar 示例
    3. backgroundColor: 背景色
      1. 实现
      2. 示例
    4. body: 页面容器
      1. 实现
      2. 示例
    5. bottomNavigationBar: 底部导航条
      1. 实现
      2. 示例
    6. bottomSheet: 一个持久停留在body下方,底部控件上方的控件
      1. 实现
      2. 示例
    7. drawer: 左侧侧边栏
      1. 实现
      2. 示例
    8. drawerDragStartBehavior: 控制侧边栏的一些特性
      1. 实现
    9. drawerEdgeDragWidth: 侧边栏弹出时非遮罩层的宽度
      1. 实现
    10. drawerEnableOpenDragGesture: 是否启用拖拽打开左侧侧边栏
      1. 实现
    11. drawerScrimColor: 侧滑栏拉出来时,用来遮盖主页面的颜色
      1. 实现
    12. endDrawer: 右侧侧边栏
      1. 实现
    13. endDrawerEnableOpenDragGesture: 是否启用拖拽打开右侧侧边栏
      1. 实现
    14. extendBody: body 是否延伸到底部控件
      1. 实现
    15. extendBodyBehindAppBar: body 是否延伸到顶部控件
      1. 实现
    16. floatingActionButton: 悬浮按钮
      1. 实现
    17. floatingActionButtonAnimator: 自定义悬浮按钮动画
      1. 实现
    18. floatingActionButtonLocation: 悬浮按钮位置
      1. 实现
    19. onDrawerChanged: 左边抽屉打开和关闭时的回调
      1. 实现
    20. onEndDrawerChanged: 右边抽屉打开和关闭时的回调
      1. 实现
    21. persistentFooterButtons: 显示在底部导航条上方的一组按钮
      1. 实现
    22. persistentFooterAlignment: 在底部导航条上方按钮的对齐方式
      1. 实现
    23. primary: 是否在屏幕顶部显示Appbar
      1. 实现
    24. resizeToAvoidBottomInset: 防止一些小组件重复
      1. 实现
    25. restorationId: 用于保存和恢复Scaffold的状态
      1. 实现

文章目录

当前版本 Flutter 3.19.5

前言

Scaffold 用于构建应用程序的基本布局结构。它提供了一个标准的应用程序布局,包括顶部的应用栏、底部的导航栏、抽屉菜单等,以及中间可变化的主体内容区域。

Scaffold API

属性

属性一览

appBar: 页面上方导航条

可以用来实现导航栏的部件有: AppBar/ Tab / TabBar / CupertinoTabBar / ObstructingPreferredSizeWidget / PreferredSize

一般不会单独把 Tab / TabBar 拿来实现appBar

实现

final PreferredSizeWidget? appBar;

AppBar 示例

Flutter入门: Scaffold 详解 - 第1张图片

Scaffold(
  appBar: AppBar(
    elevation: 1,
    title: const Text('This is a AppBar'),
    shadowColor: Colors.green,
  ),
)

完整的AppBar用法详解

Tab 示例

Flutter入门: Scaffold 详解 - 第2张图片

Scaffold(
  appBar: Tab(
    icon: Icon(Icons.directions_car),
    text: 'Tab',
    iconMargin: EdgeInsets.only(top: 50),
    height: 100,
  ),
)

TabBar 示例

Flutter入门: Scaffold 详解 - 第3张图片

return const DefaultTabController(
  length: 6,
  initialIndex: 1,
  child: Scaffold(
    appBar: TabBar(
      tabs: [
        Tab(icon: Icon(Icons.directions_car)),
        Tab(icon: Icon(Icons.directions_bike)),
        Tab(icon: Icon(Icons.directions_car)),
        Tab(icon: Icon(Icons.directions_bike)),
        Tab(icon: Icon(Icons.directions_car)),
        Tab(icon: Icon(Icons.directions_bike)),
      ],
    ),
  ),
);

完整的TabBar用法详解

CupertinoTabBar 示例

Flutter入门: Scaffold 详解 - 第4张图片

return DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: CupertinoTabBar(
      items: const [
        BottomNavigationBarItem(
          icon: Icon(CupertinoIcons.star_fill),
          label: 'Favorites',
        ),
        BottomNavigationBarItem(
          icon: Icon(CupertinoIcons.clock_solid),
          label: 'Recents',
        ),
        BottomNavigationBarItem(
          icon: Icon(CupertinoIcons.person_alt_circle_fill),
          label: 'Contacts',
        ),
        BottomNavigationBarItem(
          icon: Icon(CupertinoIcons.circle_grid_3x3_fill),
          label: 'Keypad',
        ),
      ],
    ),
  ),
);

完整的CupertinoTabBar用法详解

backgroundColor: 背景色

实现

final Color? backgroundColor;

Flutter入门: Scaffold 详解 - 第5张图片

示例

Scaffold(
  backgroundColor: Colors.green,
  appBar: AppBar(
    title: const Text('This is a AppBar'),
  ),
  body: const Center(
    child: Text('this is a body', textAlign: TextAlign.center,),
  ),
);

body: 页面容器

实现

final Widget? body;

示例

Scaffold(
  body: const Center(
    child: Text('this is a body', textAlign: TextAlign.center,),
  ),
);

bottomNavigationBar: 底部导航条

可以由任何 Widget 来实现,但实际使用中,一般由 NavigationBar 或 BottomNavigationBar 来实现,在 Material 3 版本之后 BottomNavigationBar 不再推荐使用

实现

final Widget? bottomNavigationBar;

示例

Flutter入门: Scaffold 详解 - 第6张图片

Scaffold(
  // bottomNavigationBar: Container(
  //   alignment: Alignment.center,
  //   child: Text('Hello World'),
  //   height: 50,
  //   color: Colors.green,
  // ),
  bottomNavigationBar: NavigationBar(
    destinations: const [
      NavigationDestination(
        icon: Icon(Icons.home_outlined),
        label: 'Home',
      ),
      NavigationDestination(
        icon: Icon(Icons.notifications_sharp),
        label: 'Notifications',
      ),
      NavigationDestination(
        icon: Icon(Icons.messenger_sharp),
        label: 'Messages',
      ),
    ],
  ),
);

完整的NavigationBar用法详解

bottomSheet: 一个持久停留在body下方,底部控件上方的控件

实现

final Widget? bottomSheet;

Flutter入门: Scaffold 详解 - 第7张图片

示例

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
  ),
  body: Text('this is a body'),
  bottomSheet: Container(
    child: Text('this is a bottomSheet'),
    height: 50,
  ),
  bottomNavigationBar: Container(
    child: Text('this is a bottomNavigationBar'),
    height: 50,
  ),
);

drawer: 左侧侧边栏

显示在body侧面的面板,在移动设备上通常默认是隐藏的。在屏幕上从左到右 ( TextDirection.ltr ) 或从右到左 ( TextDirection.rtl )滑动时显示

通常是Drawer组件, 要打开抽屉,请使用ScaffoldState.openDrawer函数。 要关闭抽屉,请使用ScaffoldState.closeDrawer、Navigator.pop

实现

final Widget? drawer;

Flutter入门: Scaffold 详解 - 第8张图片 Flutter入门: Scaffold 详解 - 第9张图片

示例

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
  ),
  drawer: Drawer(
    child: Center(
      child: Text('This is the Drawer'),
    ),
  ),
);

完整的 Drawer 用法详解

drawerDragStartBehavior: 控制侧边栏的一些特性

确定处理拖动启动行为的时机

DragStartBehavior.start,从屏幕侦测到手势操作时开始,拖动动画更加平滑(默认)

DragStartBehavior.down ,从首次检测到down事件时开始,拖动行为略显卡顿

实现

final DragStartBehavior drawerDragStartBehavior;

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
  ),
  drawer: Drawer(
    child: Center(
      child: Text('This is the Drawer'),
    ),
  ),
  drawerDragStartBehavior: DragStartBehavior.down,
);

drawerEdgeDragWidth: 侧边栏弹出时非遮罩层的宽度

侧边栏弹出时非遮罩层的宽度,当滑动的距离小于该值时,遮罩层会弹出。默认值是20

实现

final double? drawerEdgeDragWidth;

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
  ),
  drawer: Drawer(
    child: Center(
      child: Text('This is the Drawer'),
    ),
  ),
  drawerEdgeDragWidth: 100,
);

drawerEnableOpenDragGesture: 是否启用拖拽打开左侧侧边栏

实现

final bool drawerEnableOpenDragGesture;

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
  ),
  drawer: Drawer(
    child: Center(
      child: Text('This is the Drawer'),
    ),
  ),
  drawerEnableOpenDragGesture: false,
);

drawerScrimColor: 侧滑栏拉出来时,用来遮盖主页面的颜色

默认为Colors.black54

实现

final Color? drawerScrimColor;

Flutter入门: Scaffold 详解 - 第10张图片

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
  ),
  drawer: Drawer(
    child: Center(
      child: Text('This is the Drawer'),
    ),
  ),
  drawerScrimColor: Colors.red,
);

endDrawer: 右侧侧边栏

显示在body侧面的面板,在移动设备上通常默认是隐藏的。在屏幕上从右到左 ( TextDirection.ltr ) 或从左到右 ( TextDirection.rtl )滑动时显示

通常是Drawer组件, 要打开抽屉,请使用 ScaffoldState.openEndDrawer 函数。 要关闭抽屉,请使用ScaffoldState.closeEndDrawer、Navigator.pop

实现

final Widget? endDrawer;

Flutter入门: Scaffold 详解 - 第11张图片 Flutter入门: Scaffold 详解 - 第12张图片

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
  ),
  endDrawer: Drawer(
    child: Center(
      child: Text('This is the Drawer'),
    ),
  ),
);

endDrawerEnableOpenDragGesture: 是否启用拖拽打开右侧侧边栏

实现

final bool endDrawerEnableOpenDragGesture;

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
  ),
  endDrawer: Drawer(
    child: Center(
      child: Text('This is the Drawer'),
    ),
  ),
  endDrawerEnableOpenDragGesture: false,
);

extendBody: body 是否延伸到底部控件

如果为 true,并且 指定了bottomNavigationBar ,则主体将延伸到 Scaffold 的底部,默认为 false

实现

final bool extendBody;

Flutter入门: Scaffold 详解 - 第13张图片

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
    backgroundColor: Colors.green,
  ),
  body: Container(
    alignment: Alignment.bottomCenter,
    child: Text(
      'this is body',
      style: TextStyle(color: Colors.white, fontSize: 50),
    ),
    width: MediaQuery.of(context).size.width,
    height: MediaQuery.of(context).size.height,
    color: Colors.blue,
  ),
  bottomNavigationBar: Container(
    height: 50,
    color: Color(0x99333333),
  ),
  extendBody: true,
);

extendBodyBehindAppBar: body 是否延伸到顶部控件

默认 false,为 true 时,body 会置顶到 appbar 后,如appbar 为半透明色,可以有毛玻璃效果

实现

final bool extendBodyBehindAppBar;

Flutter入门: Scaffold 详解 - 第14张图片

Scaffold(
  appBar: AppBar(
    backgroundColor: Color(0x99333333),
  ),
  body: Container(
    alignment: Alignment.topCenter,
    child: Text(
      'this is body',
      style: TextStyle(color: Colors.white, fontSize: 50),
    ),
    width: MediaQuery.of(context).size.width,
    height: MediaQuery.of(context).size.height,
    color: Colors.blue,
  ),
  extendBodyBehindAppBar: true,
)

floatingActionButton: 悬浮按钮

通常用 FloatingActionButton 来实现

实现

final Widget? floatingActionButton;

Flutter入门: Scaffold 详解 - 第15张图片

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
    backgroundColor: Colors.green,
  ),
  floatingActionButton: FloatingActionButton(
    child: Icon(Icons.add),
    onPressed: () {},
  ),
)

floatingActionButtonAnimator: 自定义悬浮按钮动画

实现

final FloatingActionButtonAnimator? floatingActionButtonAnimator;

class NoScalingAnimation extends FloatingActionButtonAnimator{
  double _x;
  double _y;
  @override
  Offset getOffset({Offset begin, Offset end, double progress}) {
    _x = begin.dx +(end.dx - begin.dx)*progress ;
    _y = begin.dy +(end.dy - begin.dy)*progress;
    return Offset(_x,_y);
  }

  @override
  Animation getRotationAnimation({Animation parent}) {
    return Tween(begin: 1.0, end: 1.0).animate(parent);
  }

  @override
  Animation getScaleAnimation({Animation parent}) {
    return Tween(begin: 1.0, end: 1.0).animate(parent);
  }
}


Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
    backgroundColor: Colors.green,
  ),
  floatingActionButton: FloatingActionButton(
    child: Icon(Icons.add),
    onPressed: () {},
  ),
  floatingActionButtonAnimator: NoScalingAnimation(),
)

floatingActionButtonLocation: 悬浮按钮位置

实现

final FloatingActionButtonLocation? floatingActionButtonLocation;

Flutter入门: Scaffold 详解 - 第16张图片

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
    backgroundColor: Colors.green,
  ),
  floatingActionButton: FloatingActionButton(
    child: Icon(Icons.add),
    onPressed: () {},
  ),
  floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
)

onDrawerChanged: 左边抽屉打开和关闭时的回调

实现

final DrawerCallback? onDrawerChanged;

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
    backgroundColor: Colors.green,
  ),
  drawer: Drawer(
    child: Center(
      child: Text('This is the Drawer'),
    ),
  ),
  onDrawerChanged: (opened) {
    print(opened);
  },
)

onEndDrawerChanged: 右边抽屉打开和关闭时的回调

实现

final DrawerCallback? onEndDrawerChanged;

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
    backgroundColor: Colors.green,
  ),
  endDrawer: Drawer(
    child: Center(
      child: Text('This is the Drawer'),
    ),
  ),
  onEndDrawerChanged: (opened) {
    print(opened);
  },
)

persistentFooterButtons: 显示在底部导航条上方的一组按钮

实现

final List<Widget>? persistentFooterButtons;

Flutter入门: Scaffold 详解 - 第17张图片

Scaffold(
  bottomNavigationBar: NavigationBar(
    destinations: const [
      NavigationDestination(
        icon: Icon(Icons.home_outlined),
        label: 'Home',
      ),
      NavigationDestination(
        icon: Icon(Icons.notifications_sharp),
        label: 'Notifications',
      ),
      NavigationDestination(
        icon: Icon(Icons.messenger_sharp),
        label: 'Messages',
      ),
    ],
  ),
  persistentFooterButtons: const [
    Icon(Icons.add),
    Icon(Icons.remove),
    Icon(Icons.close),
    Icon(Icons.arrow_upward),
  ],
)

persistentFooterAlignment: 在底部导航条上方按钮的对齐方式

实现

final AlignmentDirectional persistentFooterAlignment;

Scaffold(
  bottomNavigationBar: NavigationBar(
    destinations: const [
      NavigationDestination(
        icon: Icon(Icons.home_outlined),
        label: 'Home',
      ),
      NavigationDestination(
        icon: Icon(Icons.notifications_sharp),
        label: 'Notifications',
      ),
      NavigationDestination(
        icon: Icon(Icons.messenger_sharp),
        label: 'Messages',
      ),
    ],
  ),
  persistentFooterButtons: const [
    Icon(Icons.add),
    Icon(Icons.remove),
    Icon(Icons.close),
    Icon(Icons.arrow_upward),
  ],
  persistentFooterAlignment: AlignmentDirectional.center,
)

primary: 是否在屏幕顶部显示Appbar

Appbar 是否向上延伸到状态栏,如电池电量,时间那一栏,默认为 true

实现

final bool primary;

Flutter入门: Scaffold 详解 - 第18张图片

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
    backgroundColor: Colors.green,
  ),
  primary: false,
)

resizeToAvoidBottomInset: 防止一些小组件重复

默认为 true

实现

final bool resizeToAvoidBottomInset;

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
    backgroundColor: Colors.green,
  ),
  resizeToAvoidBottomInset: false,
)

restorationId: 用于保存和恢复Scaffold的状态

实现

final String? restorationId;

Scaffold(
  appBar: AppBar(
    title: Text('this is a appBar'),
    backgroundColor: Colors.green,
  ),
  restorationId: 'xxxx',
)

...完...

《Flutter入门: Scaffold 详解》留言数:0

发表留言