创建程序的时候,对Scaffold感到特别陌生,所以特地学习了下,总结如下:

Scaffold总体上来说,就是一个类似android app的简易框架,借助这个框架,可以很方便的创建顶部导航栏,中间主体,右下角浮动按钮,以及底部按钮工具栏。

 home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter layout demo'),
        ),
        body: ListView(
          children: [
            Image.asset(
              'images/lake.jpg',
              width: 600,
              height: 240,
              fit: BoxFit.cover,
            ),
            titleSection,
            buttonSection,
            textSection,
          ],
        ),
      ),

参考上述代码片段, 

1 appBar

属性定义: 

AppBar({
    Key key,
    this.leading,//导航条左侧需要展示的Widget
    this.automaticallyImplyLeading = true,
    this.title,//导航条的标题
    this.actions,//导航条右侧要展示的一组widgets
    this.flexibleSpace,
    this.bottom,导航条底部需要展示的widget
    this.elevation,
    this.shape,//导航条样式
    this.backgroundColor,//导航条背景色
    this.brightness,//设置导航条上面的状态栏的dark、light状态
    this.iconTheme,//导航条上的图标主题
    this.actionsIconTheme,//导航条上右侧widgets主题
    this.textTheme,//导航条上文字主题
    this.primary = true,//为false的时候会影响leading,actions、titile组件,导致向上偏移
    this.centerTitle,//导航条表示是否居中展示
    this.titleSpacing = NavigationToolbar.kMiddleSpacing,
    this.toolbarOpacity = 1.0,
    this.bottomOpacity = 1.0,
  })

在appBar中可以放置一个widget,这个widget可以是一个Text,也可以是一个组合式的Containter,里面由多个widget组成。参考如下的示例:

Widget _appBarDemo1() {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          primary: true,//为false的时候会影响leading,actions、titile组件,导致向上偏移
          textTheme: TextTheme(//设置AppBar上面各种字体主题色
//            title: TextStyle(color: Colors.red),
          ),
          actionsIconTheme: IconThemeData(color: Colors.blue,opacity: 0.6),//设置导航右边图标的主题色,此时iconTheme对于右边图标颜色会失效
          iconTheme: IconThemeData(color: Colors.black,opacity: 0.6),//设置AppBar上面Icon的主题颜色
          brightness: Brightness.dark,//设置导航条上面的状态栏显示字体颜色
          backgroundColor: Colors.amber,//设置背景颜色
//          shape: CircleBorder(side: BorderSide(color: Colors.red, width: 5, style: BorderStyle.solid)),//设置appbar形状
//          automaticallyImplyLeading: true,//在leading为null的时候失效
          centerTitle: true,
          title: Text('AppBar Demo'),
          leading: IconButton(
              icon: Icon(Icons.add),
              onPressed: (){
                print('add click....');
              }
          ),
          actions: <Widget>[
            IconButton(icon: Icon(Icons.search), onPressed: (){print('search....');}),
            IconButton(icon: Icon(Icons.history), onPressed: (){print('history....');}),
          ],
        ),
      ),
    );
  }

2 body

用来展示 APP 的主体部分。主体部分大部分是通过组合 Container ColumnRowStack来实现的,有兴趣的可以先行搜索flutter布局,后面也会专门来写这一部分内容。

3 floatingActionButton

floatingActionButton用来定义浮动在 body 右下角的组件。Flutter 入门的那个例子中就用到了这个参数,点击右下角的浮动按钮,增加计数。

bottomNavigationBar

底部导航栏,可以传入一个 Flutter 提供的 BottomNavigationBar 来实现导航栏。示例代码:


class BottomNavigationWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => BottomNavigationWidgetState();
}

class BottomNavigationWidgetState extends State<BottomNavigationWidget> {
  final _bottomNavigationColor = Colors.blue;
  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(
              icon: Icon(
                Icons.home,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'HOME',
                style: TextStyle(color: _bottomNavigationColor),
              )),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.email,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'Email',
                style: TextStyle(color: _bottomNavigationColor),
              )),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.pages,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'PAGES',
                style: TextStyle(color: _bottomNavigationColor),
              )),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.airplay,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'AIRPLAY',
                style: TextStyle(color: _bottomNavigationColor),
              )),
        ],
        currentIndex: _currentIndex,
        onTap: (int index) {
          setState(() {
            _currentIndex = index;
          });
        },
      ),
    );
  }
} 

在上述示例代码中,增加了4个底部导航按钮,并获取了其index。实现页面响应和跳转,示例代码可参考如下的链接:Flutter | 使用BottomNavigationBar快速构建底部导航 - 简书

 5 bottomNavigationBar

 用来自定义底部导航。可以根据需要进行组合,已完成BottomNavigationBar不能实现的自定义布局。

Scaffold(
      //...省略部分代码
      floatingActionButton: FloatingActionButton(
          //悬浮按钮
          child: Icon(Icons.add),
          onPressed: () {}),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      body: pages[currentIndex],
      bottomNavigationBar: BottomAppBar(
        child: Row(
          children: <Widget>[
            SizedBox(height: 49, width: itemWidth, child: bottomAppBarItem(0)),
            SizedBox(height: 49, width: itemWidth, child: bottomAppBarItem(1)),
            SizedBox(height: 49, width: itemWidth),
            SizedBox(height: 49, width: itemWidth, child: bottomAppBarItem(2)),
            SizedBox(height: 49, width: itemWidth, child: bottomAppBarItem(3))
          ],
          mainAxisAlignment: MainAxisAlignment.spaceAround,
        ),
        shape: CircularNotchedRectangle(),
      ),
    );

效果图如下(示例代码和图片来自:Flutter 使用 BottomAppBar 自定义底部导航(中间浮出按钮) - 简书):

 

 item的自定义和响应代码示例:

Widget bottomAppBarItem(int index) {
    //设置默认未选中的状态
    TextStyle style = TextStyle(fontSize: 12, color: Colors.black);
    String imgUrl = normalImgUrls[index];
    if (currentIndex == index) {
      //选中的话
      style = TextStyle(fontSize: 13, color: Colors.blue);
      imgUrl = selectedImgUrls[index];
    }
    //构造返回的Widget
    Widget item = Container(
      child: GestureDetector(
        behavior: HitTestBehavior.opaque,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Image.asset(imgUrl, width: 25, height: 25),
            Text(
              titles[index],
              style: style,
            )
          ],
        ),
        onTap: () {
          if (currentIndex != index) {
            setState(() {
              currentIndex = index;
            });
          }
        },
      ),
    );
    return item;
  }

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐