1. 水平布局Row的使用

Flutter中的row控件就是水平控件,它可以让Row里边的子元素进行水平排列,Row控件可以分

  • 非灵活排列
  • 灵活排列

非灵活布局

  1. import 'package:flutter/material.dart';
  2. void main() => runApp(MyApp());
  3. class MyApp extends StatelessWidget {
  4. @override
  5. Widget build(BuildContext context) {
  6. return MaterialApp(
  7. title: 'ListView widget',
  8. home: Scaffold(
  9. appBar: new AppBar(
  10. title: new Text('水平方向布局'),
  11. ),
  12. body: new Row(
  13. children: <Widget>[
  14. new RaisedButton(
  15. onPressed: () {},
  16. color: Colors.redAccent,
  17. child: new Text('红色按钮')),
  18. new RaisedButton(
  19. onPressed: () {},
  20. color: Colors.orangeAccent,
  21. child: new Text('黄色按钮'),
  22. ),
  23. new RaisedButton(
  24. onPressed: () {},
  25. color: Colors.pinkAccent,
  26. child: new Text('粉色按钮'))
  27. ],
  28. )),
  29. );
  30. }
  31. }

image.png
这时候你会发现的页面已经有了三个凸起的按钮(RaisedButton),但这三个按钮并没有充满一行,而是出现了空隙。这就是不灵活横向排列造成的。它根据子元素的大小来进行排列。如果我们想实现充满一行的效果,就要使用灵活水平布局了

灵活布局

解决上面有空隙的问题,可以使用 Expanded 来进行解决,也就是我们说的灵活布局。我们在按钮的外边加入Expanded就可以了

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'ListView widget',
        home: Scaffold(
          appBar: new AppBar(
            title: new Text('水平方向布局'),
          ),
          body: Center(
            child: new Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              new RaisedButton(
                  onPressed: () {},
                  color: Colors.redAccent,
                  child: new Text('红色按钮')),
              Expanded(
                  child: new RaisedButton(
                onPressed: () {},
                color: Colors.orangeAccent,
                child: new Text('黄色按钮'),
              )),
              new RaisedButton(
                  onPressed: () {},
                  color: Colors.pinkAccent,
                  child: new Text('粉色按钮'))
            ],
          )),
        ));
  }
}

image.png

2. 垂直布局Column组件

Column组件即垂直布局控件,能够将子组件垂直排列

Column基本用法

写一段代码,在column里加入三行文字,然后看一下效果。

import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context ){
      return MaterialApp(
        title:'ListView widget',
        home:Scaffold(
          appBar:new AppBar(
            title:new Text('垂直方向布局'),
          ),
          body:Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
             Text('I am JSPang'),
             Text('my website is jspang.com'),
             Text('I love coding')
            ],
          )
        ),
      );
  }
}

这时候你会发现文字是以最长的一段文字居中对齐的,看起来很别扭。那如果想让文字以左边开始对齐,只需要加入一个对齐属性

//左对齐只要在column组件下加入下面的代码,就可以让文字左对齐
crossAxisAlignment: CrossAxisAlignment.start

Screenshot_1583474802.png

主轴和副轴的辨识

在设置对齐方式的时候你会发现右mainAxisAlignment属性,意思就是主轴对齐方式

  • main轴:如果你用column组件,那垂直就是主轴,如果你用Row组件,那水平就是主轴
  • cross轴:cross轴我们称为幅轴,是和主轴垂直的方向。比如Row组件,那垂直就是幅轴,Column组件的幅轴就是水平方向的

mainAxisAlignment 主轴对齐方式

  • mainAxisAlignment.star:头对齐
  • mainAxisAlignment.end:尾对齐
  • mainAxisAlignment.center:居中对齐

CrossAxisAlignment 副轴对齐方式

  • CrossAxisAlignment.star:头对齐
  • CrossAxisAlignment.end:尾对齐
  • CrossAxisAlignment.center:居中对齐

水平方向相对屏幕居中

让文字相对于水平方向居中,我们如何处理?其实只要加入Center组件就可以轻松解决

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ListView widget',
      home: Scaffold(
          appBar: new AppBar(
            title: new Text('垂直方向布局'),
          ),
          body: Column(
            mainAxisAlignment: MainAxisAlignment.center, //主轴(这里是垂直方向,所有主轴是垂直方向)
            children: <Widget>[
              Center(child: Text('古巴')),
              Expanded(child: Center(child: Text('一缕清风'))),
              Center(child: Text('I love coding'))
            ],
          )),
    );
  }
}

image.png

Expanded属性的使用

其实在学习水平布局的时候我们对Expanded有了深刻的理解,它就是灵活布局。比如我们想让中间区域变大,而头部区域和底部根据文字所占空间进行显示

  Expanded(child:Center(child:Text('my website is jspang.com')))

在Flutter里的布局个人觉得是很灵活的,但这就和我们写Html+CSS是一样的,我们需要些练习去熟悉它。动手练习一下吧,理论上我们学会了水平和垂直布局,已经可以布出我们想要的任何界面了

3. Stack层叠布局

水平布局和垂直布局确实很好用,但是有一种情况是无法完成的,比如放入一个图片,图片上再写一些字或者放入容器,这时候Row和Column就力不从心了。Flutter为这种情况准备了Stack层叠布局

  • 在头像上方再放入一个容器,容器里边写上字,这时候我们就可以使用Stack布局 ```dart import ‘package:flutter/material.dart’;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { var body = new Stack( alignment: const FractionalOffset(0.5, 0.8), children: [ new CircleAvatar( backgroundImage: new NetworkImage( ‘http://b-ssl.duitang.com/uploads/item/201802/20/20180220165946_RiGPS.thumb.700_0.jpeg‘), radius: 100.0, ), new Container( decoration: new BoxDecoration( color: Colors.lightBlue, ), padding: EdgeInsets.all(5.0), child: new Text(‘一缕清风’), ) ], );

var home = new Scaffold(
  appBar: new AppBar(
    title: Text('stack 布局'),
  ),
  body: Center(child: body),
);

return MaterialApp(
  title: 'stack 布局',
  home: home,
);

} }

<a name="DVKcE"></a>
#### ![tuhaokuai_1583473303.png](https://cdn.nlark.com/yuque/0/2020/png/604921/1583473322306-2d15ecd3-5ec7-4f67-9ab7-777fab356070.png#height=480&id=Nd6wY&name=tuhaokuai_1583473303.png&originHeight=480&originWidth=279&originalType=binary&size=26454&status=done&style=none&width=279)


<a name="0r41r"></a>
### 层叠布局的 alignment 属性
alignment属性是控制层叠的位置的,建议在两个内容进行层叠时使用。它有两个值X轴距离和Y轴距离,值是从0到1的,都是从上层容器的左上角开始算起的
```dart
alignment: const FractionalOffset(0.5, 0.8),

CircleAvatar组件的使用

CircleAvatar这个经常用来作头像的,组件里边有个radius的值可以设置图片的弧度。
现在我们准备放入一个图像,然后把弧度设置成100,形成一个漂亮的圆形,代码如下:

new CircleAvatar(
  backgroundImage: new NetworkImage('http://jspang.com/static//myimg/blogtouxiang.jpg'),
  radius: 100.0,
),

Stack的Positioned属性

Stack组件能进行了两个组件的层叠布局,如果是超过两个组件的层叠该如何进行定位那?那就要层叠定位组件

Positioned组件的属性
  • top 距离层叠组件上边的距离
  • bottom 距离层叠组件下边的距离
  • left 距离层叠组件左边的距离
  • right 距离层叠组件右边的距离
  • width 层叠定位组件的宽度
  • height 层叠定位组件的高度

Demo实例
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var body = new Stack(
      children: <Widget>[
        new CircleAvatar(
          backgroundImage: new NetworkImage(
              'http://jspang.com/static//myimg/blogtouxiang.jpg'),
          radius: 100.0,
        ),
        new Positioned(
          top: 10.0,
          left: 70.0,
          child: new Text('kim.com'),
        ),
        new Positioned(
          bottom: 10.0,
          right: 70.0,
          child: new Text('一缕清风'),
        )
      ],
    );
    return MaterialApp(
      title: 'ListView widget',
      home: Scaffold(
        appBar: new AppBar(
          title: new Text('层叠布局'),
        ),
        body: Center(child: body),
      ),
    );
  }
}

Screenshot_1583474697.png

4. 卡片组件布局

Flutter还有一种比较比较酷炫的布局方式,我称 它为卡片式布局。这种布局类似ViewList,但是列表会以物理卡片的形态进行展示

实例开发

比如我们现在要开发一个类似收获地址的列表,并且列表外部使用一个卡片式布局
卡片式布局默认是撑满整个外部容器的,如果你想设置卡片的宽高,需要在外部容器就进行制定。制作的效果如图

import 'package:flutter/material.dart';
void main () => runApp(MyApp());

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context ){
      var card = new Card(
         child: Column(
           children: <Widget>[
             ListTile(
               title:new Text('吉林省吉林市昌邑区',style: TextStyle(fontWeight: FontWeight.w500),),
               subtitle: new Text('技术胖:1513938888'),
               leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
             ),
             new Divider(),
              ListTile(
               title:new Text('北京市海淀区中国科技大学',style: TextStyle(fontWeight: FontWeight.w500),),
               subtitle: new Text('胜宏宇:1513938888'),
               leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
             ),
             new Divider(),
              ListTile(
               title:new Text('河南省濮阳市百姓办公楼',style: TextStyle(fontWeight: FontWeight.w500),),
               subtitle: new Text('JSPang:1513938888'),
               leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
             ),
             new Divider(),

           ],
         ),

      );


      return MaterialApp(
        title:'ListView widget',
        home:Scaffold(
          appBar:new AppBar(
            title:new Text('卡片布局'),
          ),
          body:Center(child:card),
        ),
      );
  }
}

image.png