Flutter开发之Scaffold 脚手架的使用(39)

本篇文章学习Flutter入门进阶之旅(十六)Scaffold 脚手架并修改了部分代码

  1. 增加了自定义的触发drawer、endDrawer的按钮和方法
  2. 增加了自定义tab的图片和文本的功能
  3. 涉及了onTap: 的传参功能
  4. 涉及GlobalKey 获取Scaffold触发openDrawer()的功能

Scaffold为我们提供快速搭建页面的脚手架方法。

  • appBar: 显示在界面顶部的一个菜单导航栏
  • body:页面中显示主要内容的区域,可任意指定Widget
  • floatingActionButton: 悬浮按钮(类似Android的floatingActionButton)
  • drawer、endDrawer:分别用于在左、右两侧边栏展示抽屉菜单
  • bottomNavigationBar:显示在底部的导航栏按钮栏

在Flutter中Scaffold给我们提供了上述用于快速构建页面的常用属性,开发者可根据自己的页面需求,引入不同属性达到定制出不同UI呈现的目的,下面就实际用一下Scaffold的一些功能属性。

Scaffold搭建效果图

在这里插入图片描述

这里不再一一介绍看代码更容易理解。

  1. 这里需要提一下PopupMenuButton 自带的控件
    在这里插入图片描述

  2. 5.底部导航栏 bottomNavigationBar

bottomNavigationBar的使用场景还比较多,一般我们的多页面app都会通过底部的Tab来切换App首页展示的不同内容,在Flutter的Scaffold中为我们提供了快捷用于构建底部Tab的方法,我们通过给BottomNavigationBar的Items属性设置需要展示的BottomNavigationBarItem数组即可。

 bottomNavigationBar: BottomNavigationBar(
        //不设置该属性多于三个不显示颜色
        type: BottomNavigationBarType.fixed,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("首页")),
          BottomNavigationBarItem(icon: Icon(Icons.message), title: Text("消息")),
          BottomNavigationBarItem(
              icon: Icon(Icons.add_a_photo), title: Text("动态")),
          BottomNavigationBarItem(icon: Icon(Icons.person), title: Text("我的"))
        ],
        currentIndex: _currentBottomIndex,
        fixedColor: Colors.blue,
        onTap: (index) => _onBottomTabChange(index),
      ),

在这里插入图片描述

  1. 在实现底部导航栏时,Flutter还为我们提供了一个Material组件中的类似‘"镶嵌"效果,使用BottomAppBar配合FloatingActionButton完成,文字描述可能云里雾里的。一图胜千言:悬浮按钮镶嵌在Bar上。
    在这里插入图片描述
//与FloatingActionButton配合实现"打洞"效果
      bottomNavigationBar: BottomAppBar(
        color: Colors.white,
        shape: CircularNotchedRectangle(), // 底部导航栏打一个圆形的洞
        child: Row(
          children: [
            Tab(text: "首页", icon: Icon(Icons.home)),
            Tab(text: "消息", icon: Icon(Icons.message)),
            Tab(text: "动态", icon: Icon(Icons.add_a_photo)),
            Tab(text: "我的", icon: Icon(Icons.person)),

          ],
          mainAxisAlignment: MainAxisAlignment.spaceAround, //均分底部导航栏横向空间
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => _onFabClick,
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation:
          FloatingActionButtonLocation.centerDocked, //设置FloatingActionButton的位置
    );
例子完整代码
import 'package:flutter/material.dart';

class ScaffoldWidgetTest extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new PageState();
}

class PageState extends State<ScaffoldWidgetTest> with SingleTickerProviderStateMixin {

  int _currentBottomIndex = 0; //底部tab索引
  //顶部Tab
  TabController _tabController;
  List<String> topTabLists = ["Tab 1", "Tab 2", "Tab 3"];

  @override
  void initState() {
    super.initState();
    //初始化顶部TabController
    _tabController = TabController(length: topTabLists.length, vsync: this);
    _tabController.addListener(() {
      switch (_tabController.index) {
        case 0:
          print("----111");
          break;
        case 1:
          print("----222");
          break;
        case 2:
          print("----333");
          break;
      }
    }
    );
  }

  void _onBottomTabChange(int index) {
    setState(() {
      print('_onBottomTabChange');
      _currentBottomIndex = index;
    });
  }

  void _onFabClick(int tabIndex) {
    print('_onFabClick----$tabIndex');
  }
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        // 添加leading之后需要重写点击事件唤起抽屉菜单
        // leading: Icon(Icons.account_balance),
          leading: new IconButton(
            icon: new Container(
              padding: EdgeInsets.all(3.0),
              child: new CircleAvatar(
                  radius: 30.0,
                  backgroundImage: AssetImage("images/lake.png")
              ),
            ),
            onPressed: (){
              _scaffoldKey.currentState.openDrawer();
            },
          ),


          title: Text("Scaffold 脚手架"),
          centerTitle: true,
          actions: <Widget>[
            IconButton(icon: Icon(Icons.message), onPressed: () {
              print('我来了');
              _scaffoldKey.currentState.openEndDrawer();
            }),
            IconButton(icon: Icon(Icons.access_alarm), onPressed: () {}),
            PopupMenuButton(
                onSelected: (String value) {
                  print('选项-----------------$value');
                },
                itemBuilder: (BuildContext context) => [
                  new PopupMenuItem(value: "选项一的内容", child: new Text("选项一")),
                  new PopupMenuItem(value: "选项二的内容", child: new Text("选项二")),
                  new PopupMenuItem(value: "选项三的内容", child: new Text("选项三")),
                ]
            )
          ],

          // Tab属性设置icon图标+文字
          bottom: TabBar(
            controller: _tabController,
            tabs: topTabLists
                .map((element) => Tab(
              text: element,
              icon: Icon(Icons.print),
            ))
                .toList(),
//            onTap: (index) => {},
          )
      ),

      drawer: MyDrawer(),
      endDrawer:MyDrawer(),

      body: TabBarView(
          controller: _tabController,
          children: topTabLists.map((item) {
            return Container(
              alignment: Alignment.center,
              child: Text(item),
            );
          }).toList()
      ),

//      bottomNavigationBar: BottomNavigationBar(
//        //不设置该属性多于三个不显示颜色
//        type: BottomNavigationBarType.fixed,
//        items: [
//          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("首页")),
//          BottomNavigationBarItem(icon: Icon(Icons.message), title: Text("消息")),
//          BottomNavigationBarItem(icon: Icon(Icons.add_a_photo), title: Text("动态")),
//          BottomNavigationBarItem(icon: Icon(Icons.person), title: Text("我的"))
//        ],
//        currentIndex: _currentBottomIndex,
//        fixedColor: Colors.blue,
//        onTap: (index) => _onBottomTabChange(index),
//      ),

      //与FloatingActionButton配合实现"打洞"效果
      bottomNavigationBar: BottomAppBar(
        color: Colors.white,
        shape: CircularNotchedRectangle(), // 底部导航栏打一个圆形的洞
        child: Row(
          children: [
            /*
            * IconButton(
              icon: Icon(
                Icons.home,
                color: Colors.white,
              ),
              color: Colors.white,
              onPressed: () {
                setState(() {
                  _index = 0;
                });
              },
            ),
            * */
            //  icons will default to black.
            // assert(!(text != null && null != child))不能同时存在
            GestureDetector(onTap:(){_onFabClick(0);},child: Container(width: 60,child: Tab(icon: Icon(Icons.home,color: Colors.blue),child: Text('haha',style: TextStyle(color: Colors.blue),),))),
            GestureDetector(onTap:(){_onFabClick(1);},child: Container(width: 60,child: Tab(text: "消息", icon: Icon(Icons.message)))),
            GestureDetector(onTap:(){_onFabClick(2);},child: Container(width: 60,child: Tab(text: ""))),
            GestureDetector(onTap:(){_onFabClick(3);},child: Container(width: 60,child: Tab(text: "动态", icon: Icon(Icons.add_a_photo)))),
            GestureDetector(onTap:(){_onFabClick(4);},child: Container(width: 60,child: Tab(text: "我的", icon: Icon(Icons.person)))),
          ],
          mainAxisAlignment: MainAxisAlignment.spaceAround, //均分底部导航栏横向空间
        ),
      ),

      floatingActionButton: FloatingActionButton(
        onPressed: (){_onFabClick(2);},
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, //设置FloatingActionButton的位置
    );
  }
}

class MyDrawer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Drawer(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.only(top: 88.0, bottom: 30.0),
              child: Row(
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 16.0),
                    child: ClipOval(
                      child: Image.network(
                        "https://avatar.csdn.net/6/0/6/3_xieluoxixi.jpg",
                        width: 60,
                      ),
                    ),
                  ),
                  Text(
                    "谢栋",
                    style: TextStyle(fontWeight: FontWeight.bold),
                  )
                ],
              ),
            ),
            Expanded(
              child: ListView(
                children: <Widget>[
                  ListTile(
                    leading: const Icon(Icons.settings),
                    title: const Text('个人设置'),
                  ),
                  ListTile(
                    leading: const Icon(Icons.live_help),
                    title: const Text('帮助说明'),
                  ),
                  ListTile(
                    leading: const Icon(Icons.settings),
                    title: const Text('个人设置'),
                  ),
                  ListTile(
                    leading: const Icon(Icons.live_help),
                    title: const Text('帮助说明'),
                  ),
                ],
              ),
            )
          ],
        ));
  }
}

总结:这一篇很有收获,之前感觉写了那么多flutter的文章,不知道继续研究哪方面的。现在感觉还有很多问题尚待解决。
比如:
Key,
有没有iOS 的tag,
如何获取控件改变其属性,
基础控件的使用:TextField等,
控件间的通信,
。。。

继续努力吧!!!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值