Flutter Scaffold&AppBar

2019-12-12  本文已影响0人  DDLH

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

如果给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
上一篇下一篇

猜你喜欢

热点阅读