美文网首页
Flutter Scaffold&AppBar

Flutter Scaffold&AppBar

作者: DDLH | 来源:发表于2019-12-12 20:19 被阅读0次

Scaffold是一个路由页的骨架,它包含了导航栏、抽屉菜单(Drawer)以及底部Tab导航菜单等

示例:

我们实现一个页面,它包含:

  • 一个导航栏
  • 导航栏右边有一个分享按钮
  • 有一个抽屉菜单
  • 有一个底部导航
  • 右下角有一个悬浮的动作按钮
image.png
image.png

实现代码如下:

class ScaffoldRoute extends StatefulWidget {
  @override
  _ScaffoldRouteState createState() => _ScaffoldRouteState();
}

class _ScaffoldRouteState extends State<ScaffoldRoute> {
  int _selectedIndex = 1;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        //导航栏
        title: Text("App Name"),
        actions: <Widget>[
          //导航栏右侧分享菜单
          IconButton(icon: Icon(Icons.share), onPressed: () {}),
        ],
      ),
      drawer: _drawer, //抽屉
      bottomNavigationBar: BottomNavigationBar(
        // 底部导航
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
          BottomNavigationBarItem(
              icon: Icon(Icons.business), title: Text('Business')),
          BottomNavigationBarItem(
              icon: Icon(Icons.school), title: Text('School')),
        ],
        currentIndex: _selectedIndex,
        fixedColor: Colors.blue,
        onTap: _onItemTapped,
      ),
      floatingActionButton: FloatingActionButton(
          //悬浮按钮
          child: Icon(Icons.add),
          onPressed: _onAdd),
    );
  }

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  void _onAdd() {}

  // 抽屉Drawer案例
  get _drawer => Drawer(
        child: ListView(
          padding: EdgeInsets.zero,
          children: <Widget>[
            DrawerHeader(
              decoration: BoxDecoration(
                color: Colors.lightBlueAccent,
              ),
              margin: EdgeInsets.only(bottom: 8.0),
              padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 8.0),
              child: Center(
                child: SizedBox(
                  width: 60.0,
                  height: 60.0,
                  child: CircleAvatar(
                    child: Text('R'),
                  ),
                ),
              ),
            ),
            ListTile(
              leading: Icon(Icons.settings),
              title: Text('设置'),
            ),
            Divider(), //分割线
            ListTile(
              leading: Icon(Icons.close),
              title: Text('关闭'),
              onTap: () => Navigator.pop(context), // 关闭抽屉
            )
          ],
        ),
      );
}

上面代码中我们用到了如下组件:

组件名称 解释
AppBar 一个导航栏骨架
Drawer 抽屉菜单
BottomNavigationBar 底部导航栏
FloatingActionButton 漂浮按钮

下面我们来学习一下这些组件。

AppBar

image.png

AppBar 有以下常用属性:

  • leading - 导航栏最左侧的一个控件,在首页通常显示应用的 logo;在其他界面通常显示为返回按钮。
  • automaticallyImplyLeading - 如果leading为null,是否自动实现默认的leading按钮,默认为true。
  • title - 页面标题。
  • actions → List - 一个 Widget 列表,代表 Toolbar 中所显示的菜单,对于常用的菜单,通常使用 IconButton 来表示;对于不常用的菜单通常使用 PopupMenuButton 来显示为三个点,点击后弹出二级菜单。
  • bottom - 导航栏底部菜单,通常是 TabBar。
  • elevation → double - 导航栏阴影,默认值4.0。
  • centerTitle → bool - 标题是否居中显示,默认值根据不同的操作系统,显示方式不一样。
  • backgroundColor → Color - Appbar 的颜色,默认值为 ThemeData.primaryColor。改值通常和下面的三个属性一起使用。
  • brightness → Brightness - Appbar 的亮度,有白色和黑色两种主题,默认值为 ThemeData.primaryColorBrightness。
  • iconTheme → IconThemeData - Appbar 上图标的颜色、透明度、和尺寸信息。默认值为 ThemeData.primaryIconTheme。
  • textTheme → TextTheme - Appbar 上的文字样式。

自定义leading

如果给Scaffold添加了抽屉菜单,默认情况下Scaffold会自动将AppBar的leading设置为菜单按钮(如上面截图所示),点击它便可打开抽屉菜单。如果我们想自定义菜单图标,可以手动来设置leading,如:

Scaffold(
  appBar: AppBar(
    //导航栏
    title: Text("App Name"),
    leading: Builder(builder: (context) {
      return IconButton(
        icon: Icon(Icons.dashboard, color: Colors.white), //自定义图标
        onPressed: () {
          // 打开抽屉菜单
          Scaffold.of(context).openDrawer();
        },
      );
    }),
    actions: <Widget>[
      //导航栏右侧分享菜单
      IconButton(icon: Icon(Icons.share), onPressed: () {}),
    ],
  ),
)
image.png

可以看到左侧菜单已经替换成功。

PopupMenuButton设置隐藏菜单

Scaffold(
  appBar: AppBar(
    //导航栏
    ...
    actions: <Widget>[
      //导航栏右侧分享菜单
      IconButton(icon: Icon(Icons.share), onPressed: () {}),
      // 隐藏的菜单
      new PopupMenuButton<String>(
        itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
          this.SelectView(Icons.message, '发起群聊', 'A'),
          this.SelectView(Icons.group_add, '添加服务', 'B'),
          this.SelectView(Icons.cast_connected, '扫一扫码', 'C'),
        ],
        onSelected: (String action) {
          // 点击选项的时候
          switch (action) {
            case 'A':
              break;
            case 'B':
              break;
            case 'C':
              break;
          }
        },
      ),
  ),
)

// 返回每个隐藏的菜单项
SelectView(IconData icon, String text, String id) {
  return new PopupMenuItem<String>(
      value: id,
      child: new Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          new Icon(icon, color: Colors.blue),
          new Text(text),
        ],
      ));
}
image.png
image.png

什么是SliverAppBar

SliverAppBar 类似于Android中的CollapsingToolbarLayout,可以轻松实现页面头部展开、合并的效果。
与AppBar大部分的属性重合,相当于AppBar的加强版。

return Scaffold(
  body: new CustomScrollView(
    slivers: <Widget>[
      new SliverAppBar(
        // title: Text("标题"),
        // flexibleSpace: new FlexibleSpaceBar(  //滑动标题上移效果,去掉title
        //   title: new Text("标题标题标题"),
        //   centerTitle: true,
        //   collapseMode: CollapseMode.pin,
        // ),
        flexibleSpace: new FlexibleSpaceBar(
          background: Image.asset('images/1.jpg', fit: BoxFit.fill),
          title: new Text("标题标题标题"),
        ),
      ),
      new SliverFixedExtentList(
        itemExtent: 50.0,
        delegate: new SliverChildBuilderDelegate(
          (context, index) => new ListTile(
                title: new Text("Item $index"),
              ),
          childCount: 30,
        ),
      ),
    ],
  ),
);
image.png image.png

相关文章

网友评论

      本文标题:Flutter Scaffold&AppBar

      本文链接:https://www.haomeiwen.com/subject/cdsegctx.html