Flutter学习之Scaffold控件

717 阅读5分钟

前言

在上篇文章里面学习了 MaterialApp 的使用,不过没有提到 Scaffold 控件,这两个控件一般是搭配来使用,下面就来学习下 Scaffold 控件的使用。

使用

下面就先来个使用 demo

void main() {
  runApp(const NewsApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: "News App",
        theme: ThemeData(
          primaryColor: Colors.white,
        ),
        home: const _MyHome(title: 'home title'),
    );
  }
}
class _MyHome extends StatefulWidget {
  const _MyHome({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<StatefulWidget> createState() {
    return _MyHomeState();
  }
}

class _MyHomeState extends State<_MyHome> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
    
    );
  }
}

声明好后 Scaffold 控件后,接下来就来熟悉下它的那些属性

属性

appBar

App 标题栏,使用

return Scaffold(
  appBar: AppBar(
    title: Text(widget.title),
  )
);

AppBar 里面又为我们提供了不同的属性

  • leading

最左边按钮 Widget,可以设置图标,文字等等。

appBar: AppBar(
  leading: Center(
    child: GestureDetector(
      onTap: () {
        //返回的点击事件
      },
      child: const Text('返回'),
    ),
  ),
  title: Text("头部头部头部头部头部头部头部头部头部头部头部头部头部头部头部头部头部头部头部头部"),
)

image.png

  • automaticallyImplyLeading

结合 leading 来使用,当 leading 不为 null 的时候无效,它的作用是是否需要自动推断 leading 是什么 Widget。默认为 true,如果设置为 false 并且 leading 为 null 的时候,那么这块的区域就会给到 title 来展示。

  • title

标题栏标题,例如上面例子里面的 Text ,默认 Android 居左,IOS 居中,

image.png

那如果 Android 也要居中呢,怎么弄?正好,flutter 也给我们提供了属性 centerTitle 设置为 true 就好了。

appBar: AppBar(
  centerTitle: true,
  title: const Text("头部"),
)

image.png

  • actions

最右边的按钮控件,可以提供多个,需要配置一个 List

actions: <Widget>[
  IconButton(
    icon: const Icon(Icons.shopping_cart),
    tooltip: '购物车',
    onPressed: () {
      // handle the press
    },
  ),
  IconButton(
    icon: const Icon(Icons.share),
    tooltip: '分享',
    onPressed: () {
      // handle the press
    },
  ),
],

image.png

也可以通过 PopupMenuButton 来弹出一个菜单栏

enum MenuItem { share, search }

class _MyHomeState extends State<_MyHome> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          leading: Center(
            child: GestureDetector(
              onTap: () {
                //返回的点击事件
              },
              child: const Text('返回'),
            ),
          ),
          centerTitle: true,
          title: const Text("头部"),
          actions: <Widget>[
            PopupMenuButton<MenuItem>(
              onSelected: (MenuItem result) {
              },
              icon: const Icon(Icons.menu),
              itemBuilder: (BuildContext context) =>
                  <PopupMenuEntry<MenuItem>>[
                const PopupMenuItem<MenuItem>(
                  value: MenuItem.share,
                  child: Text('分享'),
                ),
                const PopupMenuItem<MenuItem>(
                  value: MenuItem.search,
                  child: Text('搜索'),
                ),
              ],
            ),
          ]),
    );
  }
}

image.png

  • flexibleSpace

需要配合 CustomScrollView,SliverAppBar,expandedHeight 一起使用,实现一个滚动头部折叠效果,expandHeight 代表 flexibleSpace 的高度,flexibleSpace 是展开和折叠效果,类似 Android 里面的 CoordinatorLayout 控件 AppBar 的折叠效果,这个可以后续学习。

flexibleSpace:FlexibleSpaceBar(),
  • bottom

TabBar,类似 Android 里面的 TabLayout 控件,需要结合 DefaultTabController 和 TabBarView 来使用。

class _MyHomeState extends State<_MyHome> {
  final List<Tab> appBarTabs = <Tab>[    const Tab(text: '要闻'),    const Tab(text: '体育'),    const Tab(text: '娱乐')  ];

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: appBarTabs.length,
      child: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: const Text("标题"),
          bottom: TabBar(tabs: appBarTabs),
        ),
        body: const TabBarView(children: <Widget>[
          Center(child: Text('要闻内容')),
          Center(child: Text('体育内容')),
          Center(child: Text('娱乐内容'))
        ]),
      ),
    );
  }
}

image.png

  • elevation AppBar 的阴影值,默认为 4

  • shadowColor

阴影颜色

  • shape

当 elevation 大于 0 ,该属性有效,定义阴影的形状。有 RoundedRectangleBorder,ContinuousRectangleBorder,BeveledRectangleBorder。

  • backgroundColor appBar 背景颜色

  • foregroundColor

appBar 前景色

  • brightness AppBar 的亮度,有白天 Brightness.light 和黑夜模式 Brightness.dark

  • iconTheme AppBar 图标的样式 ,通过 IconTheme.of(context) 可以进行设置

  • actionsIconTheme actions 属性设置的图标的样式,使用通 iconTheme

  • textTheme appBar 文字主题样式 可以使用 Theme.of(context).textTheme 来进行设置

  • primary appBar 内容是否 嵌入 StatusBar 里面。false 为 嵌入

  • centerTitle 标题是否居中显示

  • titleSpacing 标题左右间距

  • toolbarOpacity 应用程序栏的工具栏的透明程度。值 1.0 是完全不透明的,值 0.0 是完全透明的

  • bottomOpacity appBar 底部透明度,结合 bottom 属性使用设置方式同 toolbarOpacity

  • toolbarHeight

appBar 高度,默认为 56

  • leadingWidth

左边图标的宽度

  • backwardsCompatibility false 的时候使用 systemOverlayStyle 属性,已过时

  • toolbarTextStyle

appBar 文本的样式

  • titleTextStyle

appBar 标题的样式

  • systemOverlayStyle

设置状态栏的文本样式

body

内容区域的布局

body: Center(
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: const <Widget>[
      Text(
        'Hello Flutter',
      ),
    ],
  ),
),

image.png

floatingActionButton

底部浮动按钮

floatingActionButton: FloatingActionButton(
  onPressed: (){

  },
  tooltip: 'Increment',
  child: const Icon(Icons.add),
)

image.png

  • child

FloatingActionButton 的布局

  • tooltip

FloatingActionButton 控件长按显示的提示文本

  • foregroundColor

FloatingActionButton 的前景色

  • backgroundColor

FloatingActionButton 的背景色

  • focusColor

FloatingActionButton 获取到焦点的时候按钮显示的颜色

  • hoverColor

给 web 端用,鼠标悬浮到按钮时候的颜色

  • splashColor

水波纹颜色

  • heroTag

设置 Tag ,防止同一个页面两个 FloatingActionButton 冲突问题

  • elevation

阴影值

  • focusElevation

聚焦阴影值

  • hoverElevation

鼠标悬浮状态阴影值

  • highlightElevation

高亮对应的阴影值

  • disabledElevation

按钮禁用时的阴影值

  • onPressed

按钮点击事件

  • MouseCursor

鼠标悬停区域时的光标样式

  • mini

是小图标还是大图标

  • shape

按钮的形状(矩形 Border,圆形图标 CircleBorder )

  • clipBehavior

Clip.antiAlias 剪辑具有抗锯齿功; Clip.antiAliasWithSaveLayer 在剪辑后立即剪辑具有抗锯齿和 saveLayer :Clip.hardEdge:剪辑,但不应用抗锯齿;Clip.none:不剪辑。

  • focusNode

FocusNode,对焦点事件的一些设置和处理

  • autofocus

是否自动聚焦

  • materialTapTargetSize

点击的效果

  • isExtended

是否有一个过渡的动画

  • enableFeedback

为特定操作提供平台特定反馈。

floatingActionButtonLocation

设置 FloatingActionButton 的位置

image.png

floatingActionButtonAnimator

FloatingActionButton 控件出现或消失的动画

floatingActionButtonAnimator: FloatingActionButtonAnimator.scaling

persistentFooterButtons

固定在下方显示的按钮,比如对话框下方的确定、取消按钮

image.png

drawer

右滑从左边出来的侧边栏

drawer: const Drawer(
  child: UserAccountsDrawerHeader(
    accountName: Text(
      "Flutter",
    ),
    accountEmail: Text(
      "Flutter@gmail.com",
    ),
  ),
),

image.png

onDrawerChanged

从左边滑动出来的侧边栏滑动监听事件

endDrawer

从右边滑动出来的侧边栏

onEndDrawerChanged

从右边滑动出来的侧边栏监听事件

bottomNavigationBar

显示在页面底部的导航栏

bottomNavigationBar:BottomNavigationBar(
  items:const [
    BottomNavigationBarItem(
      icon: Icon(Icons.home),
      label: '首页',
    ),
    BottomNavigationBarItem(
      icon: Icon(Icons.home),
      label: '社区',
    ),
    BottomNavigationBarItem(
      icon: Icon(Icons.home),
      label: '我的',
    ),
  ],
  currentIndex:0,
),

image.png

bottomSheet

从底部滑动出来的弹框,类似 Android 的 BottomSheetDialog。

bottomSheet: BottomSheet(
  onClosing: () {
    print("closed");
  },
  builder: (context) {
    return Container(
      height: 300,
      color: Colors.yellow,
      alignment: Alignment.centerLeft,
      child: const Text("BottomSheet In Scaffold"),
    );
  },
)

image.png

或者通过点击事件弹出来

floatingActionButton: FloatingActionButton(
  onPressed: () {
    showModalBottomSheet(
      context: context,
      builder: (context) {
        return Container(
          height: 300,
          color: Colors.yellow,
          alignment: Alignment.centerLeft,
          child: const Text("BottomSheet In Scaffold"),
        );
      },
    );
  },
  tooltip: 'Increment',
  child: const Icon(Icons.add),
),

点击后 floatingActionButton 就会弹出,效果图如下

image.png

backgroundColor

Scaffold 的背景颜色

resizeToAvoidBottomInset

键盘弹出时候,允许重新计算大小,防止键盘挡住,默认为 true

primary

布局是否显示到顶部状态栏,默认为 true

drawerDragStartBehavior

默认为 DragStartBehavior.start ,还有一种为 DragStartBehavior.down,打开和关闭 drawer 的行为

extendBody

是否延伸body至底部

extendBodyBehindAppBar

是否延伸 body 到顶部

drawerScrimColor

当抽屉打开时,遮罩层的颜色。

drawerEdgeDragWidth

可打开抽屉的拖动宽度

drawerEnableOpenDragGesture

左侧是否可以滑出抽屉

endDrawerEnableOpenDragGesture

右侧是否可以滑出抽屉

restorationId

restore ID 用于保存和恢复 Scaffold 的状态。

总结

好了,Scaffold 先学习到这里,上面分别简单学习了 AppBar,FloatingActionButton , bottomSheet 等等属性的学习。记录下,方便后面查看。