Flutter 页面布局

注释:
上面主要介绍页面布局的概念,下面是一些代码


7.1 页面基本布局

7.1.1 Container(容器布局)

Container(容器布局)在Flutter里大量使用,它是一个组合Widget,内部有绘制Widget,定位Widget和尺寸Widget.

7.1.2 Center(居中布局)

7.1.3 Padding(填充布局)

Padding 即为填充组件,用于处理容器与其元素之间的间距,与Padding属性对应的是margin属性,margin处理容器与其他组件之间的间距。

7.1.4(对齐布局)

Align组件即对齐组件,能将组件按指定方式对齐,并根据子组件的大小调整自己的大小。
对齐子控件的方式:

bottomCenter    (0.5, 1.0)    底部中心
bottomLeft    (0.0, 1.0)    左下角
bottomRight    (1.0, 1.0)    右下角
center    (0.5, 0.5)    水平垂直居中
centerLeft    (0.0, 0.5)    左边缘中心
centerRight    (1.0, 0.5)    右边缘中心
topCenter    (0.5, 0.0)    顶部中心
topLeft    (0.0, 0.0)    左上角
topRight    (1.0, 0.0)    右上角

7.1.5(水平布局)

水平布局是一种常用的布局方式,我们主要使用Row组件来完成子组件在水平方向的排列。
Row组件常见的属性如下展示:

mainAxisAlignment: 子元素在主轴的对齐方式,Row的主轴即为水平方向
mainAxisSize: 主轴方向大小适配方式,只有两种取值方式:
MainAxisSize.max 主轴方向大小(在Row中指宽度)与父容器大小相同(即Android中的match_parent)
MainAxisSize.min 主轴方向大小(在Row中指宽度)由子元素决定(即Android中的wrap_content)
crossAxisAlignment: 子元素在交叉轴(垂直方向)的对齐方式
children: 子元素列表

对于Row来说,水平方向是主轴,垂直方向是次轴,可以完全参照Web中Flex布局

7.1.6 Column(垂直方向)

Column组件常见的属性如下展示:

mainAxisAlignment: 子元素在主轴的对齐方式,Row的主轴即为水平方向
mainAxisSize: 主轴方向大小适配方式,只有两种取值方式:
MainAxisSize.max 主轴方向大小(在Row中指宽度)与父容器大小相同(即Android中的match_parent)
MainAxisSize.min 主轴方向大小(在Row中指宽度)由子元素决定(即Android中的wrap_content)
crossAxisAlignment: 子元素在交叉轴(垂直方向)的对齐方式
children: 子元素列表

对于Column来说,垂直方向是主轴,水平方向是次轴,可以完全参照Web中Flex布局

7.1.7 FittedBox(缩放布局)

FittedBox组件主要做两件事情,缩放(Scale)和位置调整(Position)

7.1.8 Stack/Alignment

7.1.9 Stack/Positioned

7.1.10 IndexedStack

7.1.11 OverflowBox 溢出父容器显示


7.2 宽高尺寸处理

7.2.1 SizeBox(设置具体尺寸)

7.2.2 ConstrainedBox(限定最大最小宽高布局)

7.2.3 LimitedBox(限定最大宽高布局)

7.2.4 AspectRatio(调整宽高比)

7.2.5 FractionallySizeBox(百分比布局)


7.3 列表及表格布局

7.3.1 ListView

7.3.2 GridView

7.3.3 Table


7.4 其他布局处理

7.4.1 Transform(矩阵转换)

7.4.2 Baseline(基准线布局)

7.4.3 Offstage(控制是否显示组件)

7.4.4 Wrap(按宽高自动换行布局)


7.5 综合布局

如下面Demo_7.5_布局综合示例


代码示例

import 'package:flutter/material.dart';

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

class  MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Align对齐布局示例',
      // 自定义主题,主题颜色为绿色风格
      theme: ThemeData(
        brightness: Brightness.light,//应用程序整体主题的亮度
        primaryColor: Colors.lightGreen[600],//App主要部分的颜色
        accentColor: Colors.orange[600],//前景色(文本、按钮等)
      ),
      home: LayoutDemo5(),
    );
  }
}

// Demo_7.5_布局综合示例
// 布局综合示例
class LayoutDemo25 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build

    //风景区地址部分
    Widget addressContainer = Container(
      padding: EdgeInsets.all(32.0),//此部分四周间隔一定距离
      child: Row(
        children: <Widget>[
          // Expanded填充左右组件的空隙部分
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,//顶部对齐
              children: <Widget>[
                Container(
                  padding: EdgeInsets.only(bottom: 8.0),//与上下文本间隔一定距离
                  child: Text(
                    '风景区地址',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
                Text(
                  '湖北省十堰市丹江口市',
                  style: TextStyle(
                    color: Colors.grey[500],
                  ),
                )
              ],
            ),
          ),
          Icon(
            Icons.star,
            color: Colors.red[500],
          ),
          Text(
            '66'
          )
        ],
      ),
    );

    // 构建按钮组中单个按钮 参数为图标及文本
    Column buildButtonColumn(IconData icon, String label) {
      return Column(
        mainAxisSize: MainAxisSize.min,//垂直方向大小最小化
        mainAxisAlignment: MainAxisAlignment.center,//垂直方向居中对齐
        children: <Widget>[
          Icon(
            icon,
            color: Colors.lightGreen[600],//上面部分图标
          ),
          Container(
            margin: EdgeInsets.only(top: 8.0),
            child: Text(
              label,
              style: TextStyle(
                fontSize: 12.0,
                fontWeight: FontWeight.w400,
                color: Colors.lightGreen[600],
              ),
            ),
          )

        ],

      );
    }

    //按钮组部分
    Widget buttonsContainer = Container(

      //容器横向布局
      child: Row(
        /*
          enum MainAxisAlignment {
              //将子控件放在主轴的开始位置
              start,  
              //将子控件放在主轴的结束位置
              end,
              //将子控件放在主轴的中间位置
              center,
              //将主轴空白位置进行均分,排列子元素,手尾没有空隙
              spaceBetween,
              //将主轴空白区域均分,使中间各个子控件间距相等,首尾子控件间距为中间子控件间距的一半
              spaceAround,
              //将主轴空白区域均分,使各个子控件间距相等
              spaceEvenly,
          }
        */
        mainAxisAlignment: MainAxisAlignment.spaceAround,//水平方向均匀排列每个元素
        children: <Widget>[
          buildButtonColumn(Icons.call, '电话'),
          buildButtonColumn(Icons.near_me, '导航'),
          buildButtonColumn(Icons.share, '分享'),
        ],
      ),
    );

    //风景区介绍文本部分
    Widget textContainar = Container(
      padding: EdgeInsets.all(32.0),
      //文本块一定是用'''来引用起来
      child: Text(
        '''
        武当山,中国道教圣地,又名太和山、谢罗山、参上山、仙室山,古有“太岳”、“玄岳”、“大岳”之称。位于湖北西北部十堰市丹江口市境内。东接闻名古城襄阳市,西靠车城十堰市 ,南望原始森林神农架,北临高峡平湖 丹江口水库。
明代,武当山被皇帝封为“大岳”、“治世玄岳”,被尊为“皇室家庙”。武当山以“四大名山皆拱揖,五方仙岳共朝宗”的“五岳之冠”地位闻名于世。 [1] 
1994年12月,武当山古建筑群入选《世界遗产名录》,2006年被整体列为“全国重点文物保护单位” [2]  。2007年,武当山和长城、丽江、周庄等景区一起入选 “欧洲人最喜爱的中国十大景区”。2010至2013年,武当山分别被评为国家5A级旅游区、国家森林公园、中国十大避暑名山、海峡两岸交流基地,入选最美 “国家地质公园”。 [3-7] 
截至2013年,武当山有古建筑53处,建筑面积2.7万平方米,建筑遗址9处,占地面积20多万平方米,全山保存各类文物5035件。 [8-9] 
武当山是道教名山和武当武术的发源地,被称为“亘古无双胜境,天下第一仙山”。武当武术,是中华武术的重要流派。元末明初,道士张三丰集其大成,开创武当派。
        ''',
        softWrap: true,

      ),
    );

    return Scaffold(
        appBar: AppBar(
          title: Text(
            '武当山风景区',
            style: TextStyle(
              color: Colors.white,
            ),
          ),
        ),
        body: ListView(
          children: <Widget>[
            Image.asset(
              'images/wudangshan.jpg',
              width: 100.0,
              height: 240.0,
              fit: BoxFit.cover,//图片填充整个父容器
            ),
            addressContainer,
            buttonsContainer,
            textContainar,
          ],
        ),
      );
  }
}



// Demo_7.4.4_Wrap(按宽高自动换行布局)
// Wrap(按宽高自动换行布局)
class LayoutDemo24 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Wrap(按宽高自动换行布局)'),
      ),
      body: Wrap(
        spacing: 8.0,//Chip之间的间隙大小
        runSpacing: 4.0,//行之间的间隙大小
        children: <Widget>[
          Chip(
            //添加圆形头像
            avatar: CircleAvatar(
              backgroundColor: Colors.lightGreen.shade800,
              child: Text(
                '西门',
                style: TextStyle(
                  fontSize: 10.0,
                ),
              ),
            ),
            label: Text('西门吹雪'),
          ),
          Chip(
            //添加圆形头像
            avatar: CircleAvatar(
              backgroundColor: Colors.lightGreen.shade800,
              child: Text(
                '摘星',
                style: TextStyle(
                  fontSize: 10.0,
                ),
              ),
            ),
            label: Text('司空摘星'),
          ),
          Chip(
            //添加圆形头像
            avatar: CircleAvatar(
              backgroundColor: Colors.lightGreen.shade800,
              child: Text(
                '鱼儿',
                style: TextStyle(
                  fontSize: 10.0,
                ),
              ),
            ),
            label: Text('小鱼儿小鱼儿'),
          ),
          Chip(
            //添加圆形头像
            avatar: CircleAvatar(
              backgroundColor: Colors.lightGreen.shade800,
              child: Text(
                '一郎',
                style: TextStyle(
                  fontSize: 10.0,
                ),
              ),
            ),
            label: Text('萧十一郎'),
          ),
        ],
      ),
    );
  }
}

// Demo_7.4.3_Offstage(控制是否显示组件)
// Offstage(控制是否显示组件)
class LayoutDemo23 extends StatefulWidget {
  final String title;

  LayoutDemo23({Key key,this.title}):super(key: key);

  @override
  _LayoutDemo23State createState() => _LayoutDemo23State();
}

class _LayoutDemo23State extends State<LayoutDemo23> {
  //状态控制是否显示文本组件
  bool offstage = true;
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('widget.title'),
      ),
      body: Center(
        child: Offstage(
          offstage: offstage,//控制是否显示
          child: Text(
            '我出来了',
            style: TextStyle(
              fontSize: 36.0,
            ),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          //设置是否显示文本组件
          setState(() {
            offstage = !offstage;
          });
        },
        tooltip: '显示隐藏',
        child: Icon(Icons.flip),
      ),
    );
  }
}


// Demo_7.4.2_Baseline(基准线布局)
// Baseline(基准线布局)
class LayoutDemo22 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Baseline(基准线布局示例)'),
      ),
      body: Row(
        //水平等间距排列子组件
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          //设置基准线
          Baseline(
            baseline: 100.0,
            //对齐字符底部水平线
            baselineType: TextBaseline.alphabetic,
            child: Text(
              'AaBbCc',
               style: TextStyle(
                fontSize: 18.0,
                textBaseline: TextBaseline.alphabetic,
               ),
            ),
          ),
          Baseline(
            baseline: 100.0,
            //对齐字符底部水平线
            baselineType: TextBaseline.alphabetic,
            child: Container(
              width: 40.0,
              height: 40.0,
              color: Colors.green,
            )
          ),
          Baseline(
            baseline: 100.0,
            //对齐字符底部水平线
            baselineType: TextBaseline.alphabetic,
            child: Text(
              'AaBbCc',
               style: TextStyle(
                fontSize: 26.0,
                textBaseline: TextBaseline.alphabetic,
               ),
            ),
          ),
        ],
      ),
    );
  }
}

// Demo_7.4.1_Transform(矩阵转换)
// Transform矩阵转换示例
class LayoutDemo21 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Transform矩阵转换示例'),
      ),
      body: Center(
        child: Container(
          color: Colors.grey,
          child: Transform(
            alignment: Alignment.topRight,
            transform: Matrix4.rotationZ(0.3),
            child: Container(
              padding: EdgeInsets.all(8.0),
              color: Color(0xFFE8581C),
              child: Text('Transform矩阵转换'),
            ),
          ),
        ),
      ),
    );
  }
}

// Demo_7.3.3_Table
// Table表格布局示例
class LayoutDemo20 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Table表格布局示例'),
      ),
      body: Center(
        child: Table(
          //设置表格有多少列,并且指定列宽
          columnWidths: {
            0: FixedColumnWidth(100.0),
            1: FixedColumnWidth(40.0),
            2: FixedColumnWidth(80.0),
            3: FixedColumnWidth(80.0)
          },
          //设置表格边框样式
          border: TableBorder.all(
            color: Colors.black38,
            width: 2.0,
            style: BorderStyle.solid,
          ),
          children: [
            //添加第一行数据
            TableRow(
              children: [
                Text('姓名'),
                Text('性别'),
                Text('年龄'),
                Text('身高'),
              ],
            ),
            TableRow(
              children: [
                Text('张三'),
                Text('男'),
                Text('26'),
                Text('172'),
              ],
            ),
            TableRow(
              children: [
                Text('李四'),
                Text('男'),
                Text('28'),
                Text('178'),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

// Demo_7.3.2_GridView
// GridView九宫格示例
class LayoutDemo19 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build

    // 使用generate构造图片列表
    List<Container> _buildGridTitleList(int count){
      return List<Container>.generate(
        count, 
        (int index) => new Container(
          child: Image.asset('images/pic.jpg'),
        ));
    }

    // 渲染GridView
    Widget buildGrid() {
      return GridView.extent(
        maxCrossAxisExtent: 150.0,//次轴的宽度
        padding: EdgeInsets.all(4.0),//上下左右内边军
        mainAxisSpacing: 4.0,//主轴间隙
        crossAxisSpacing: 4.0,//次轴间隙
        children: _buildGridTitleList(9),//添加9个元素
      );
    }
    return Scaffold(
      appBar: AppBar(
        title: Text('GridView九宫格示例'),
      ),
      body: Center(
        child: buildGrid(),
      ),
    );
  }
}

// Demo_7.3.1.1_ListView_滚动布局示例
// ListView_滚动布局示例
class LayoutDemo18 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('滚动布局示例'),
      ),
      body: ListView(
        children: <Widget>[
          Center(
            child: Text(
              '\n广州河区公园',
              style: TextStyle(
                fontSize: 30.0
              ),
            ),
          ),
          Center(
            child: Text(
              '天河公园',
              style: TextStyle(
                fontSize: 16.0,
              ),
            ),
          ),
          Center(
            child: Text(
              '天河公园,是区属综合性公园,位于广州天河区员村,西靠天府路,南连黄埔大道,北接中山大道,来往交通十分便利。公园总面积为70.7公顷,水体面积占10公顷。天河公园以自然生态景观为主要特色,公园规划为五个功能区:百花园景区、文体娱乐区、老人活动区、森林休憩区、后勤管理区。',
              style: TextStyle(
                fontSize: 14.0,
              ),
            ),
          )
        ],
      ),
    );
  }
}

// Demo_7.3.1_ListView
// ListView布局示例
class LayoutDemo17 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build

    List<Widget> list = <Widget>[
      ListTile(
        title: Text(
          '广州市黄埔大道建中路店',
          style: TextStyle(
            fontWeight: FontWeight.w400,
            fontSize: 18.0,
          ),
        ),
        subtitle: Text('广州市福黄浦大道建中路3号'),
        leading: Icon(
          Icons.fastfood,
          color: Colors.orange,
        ),
      ),
      ListTile(
        title: Text(
          '广州市黄埔大道建中路店',
          style: TextStyle(
            fontWeight: FontWeight.w400,
            fontSize: 18.0,
          ),
        ),
        subtitle: Text('广州市福黄浦大道建中路3号'),
        leading: Icon(
          Icons.fastfood,
          color: Colors.orange,
        ),
      ),
      ListTile(
        title: Text(
          '广州市黄埔大道建中路店',
          style: TextStyle(
            fontWeight: FontWeight.w400,
            fontSize: 18.0,
          ),
        ),
        subtitle: Text('广州市福黄浦大道建中路3号'),
        leading: Icon(
          Icons.fastfood,
          color: Colors.orange,
        ),
      ),
      ListTile(
        title: Text(
          '广州市黄埔大道建中路店',
          style: TextStyle(
            fontWeight: FontWeight.w400,
            fontSize: 18.0,
          ),
        ),
        subtitle: Text('广州市福黄浦大道建中路3号'),
        leading: Icon(
          Icons.fastfood,
          color: Colors.orange,
        ),
      ),
      ListTile(
        title: Text(
          '广州市黄埔大道建中路店',
          style: TextStyle(
            fontWeight: FontWeight.w400,
            fontSize: 18.0,
          ),
        ),
        subtitle: Text('广州市福黄浦大道建中路3号'),
        leading: Icon(
          Icons.fastfood,
          color: Colors.orange,
        ),
      ),
      ListTile(
        title: Text(
          '广州市黄埔大道建中路店',
          style: TextStyle(
            fontWeight: FontWeight.w400,
            fontSize: 18.0,
          ),
        ),
        subtitle: Text('广州市福黄浦大道建中路3号'),
        leading: Icon(
          Icons.fastfood,
          color: Colors.orange,
        ),
      )
    ];

    return Scaffold(
      appBar: AppBar(
        title: Text('ListView布局示例'),
      ),
      body: Center(
        child: ListView(
          children: list,
        ),
      ),
    );
  }
}


// Demo_7.2.5_FractionallySizeBox(百分比布局)
// FractionallySizeBox(百分比布局)
class LayoutDemo16 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('FractionallySizeBox(百分比布局)'),
      ),
      body: Container(
        color: Colors.blueGrey,
        height: 200.0,
        width: 200.0,
        child: FractionallySizedBox(
          alignment: Alignment.topLeft,//元素左上角对齐
          widthFactor: 0.5,//宽度因子
          heightFactor: 1.5,//高度因子
          child: Container(
            color: Colors.green,
          ),
        ),
      ),
    );
  }
}

// Demo_7.2.4_AspectRatio(调整宽高比)
// AspectRatio(调整宽高比)
class LayoutDemo15 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('AspectRatio(调整宽高比)'),
      ),
      body: Container(
        height: 200.0,
        child: AspectRatio(
          aspectRatio: 1.5,//比例可以调整(宽高比)
          child: Container(
            color: Colors.green,
          ),
        ),
      ),
    );
  }
}

// Demo_7.2.3_LimitedBox(限定最大宽高布局)
// LimitedBox(限定最大宽高布局)
class LayoutDemo14 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('LimitedBox(限定最大宽高布局)'),
      ),
      body: Row(
        children: <Widget>[
          Container(
            color: Colors.grey,
            width: 100.0,
          ),
          LimitedBox(
            maxWidth: 100.0,//设置最大宽度,限定child在此范围内
            child: Container(
              color: Colors.lightGreen,
              width: 250.0,
            ),
          )
        ],
      ),
    );
  }
}

// Demo_7.2.2_ConstrainedBox(限定最大最小宽高布局)
// ConstrainedBox(限定最大最小宽高布局)
class LayoutDemo13 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('ConstrainedBox(限定最大最小宽高布局)'),
      ),
      body: ConstrainedBox(
        constraints: BoxConstraints(
          minWidth: 150.0,
          minHeight: 150.0,
          maxHeight: 220.0,
          maxWidth: 220.0
        ),
        child: Container(
          width: 300.0,
          height: 300.0,
          color: Colors.green,
        ),
      ),
    );
  }
}



// Demo_7.2.1_SizeBox(设置具体尺寸)
// SizeBox设置具体尺寸
class LayoutDemo12 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('SizeBox设置具体尺寸示例'),
      ),
      body: SizedBox(
        //固定宽为200.0,高为300,
        width: 200.0,
        height: 300.0,
        child: Card(
          child: Text(
            'SizeBox',
            style: TextStyle(
              fontSize: 36.0,
            ),
            ),
        ),
      ),
    );
  }
}

// Demo_11_OverflowBox 溢出父容器显示
// OverflowBox 溢出父容器显示
class LayoutDemo11 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('overflowBox溢出父容器显示示例'),
      ),
      body: Container(
        color: Colors.green,
        width: 200.0,
        height: 200.0,
        padding: EdgeInsets.all(5.0),
        child: OverflowBox(
          alignment: Alignment.topLeft,
          maxWidth: 300.0,
          maxHeight: 500.0,
          child: Container(
            color: Colors.blueGrey,
            width: 400.0,
            height: 400.0,
          ),
        ),
      ),
    );
  }
}

// Demo_10_indexedStack
// indexedStack
class LayoutDemo10 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Stack层叠布局示例'),
      ),
      body: Center(
        child: IndexedStack(
          index: 1,//设置索引为1就只显示文本内容了
          alignment: FractionalOffset(0.2, 0.2),
          children: <Widget>[
            CircleAvatar(
              backgroundImage: AssetImage('images/pic.jpg'),
              radius: 100.0,
            ),
            Container(
              decoration: BoxDecoration(
                color: Colors.black38,
              ),
              child: Text(
                '我是超级飞侠',
                style: TextStyle(
                  fontSize: 22.0,
                  fontWeight: FontWeight.bold,
                  color: Colors.white
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

// Demo_9_Stack/Positioned
// Stack/Positioned
class LayoutDemo9 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('层叠定位布局示例'),
      ),
      body: Center(
        //添加层叠布局
        child: Stack(
          children: <Widget>[
            //添加图片
            Image.asset('images/pic.jpg'),
            //设置定位布局
            Positioned(
              bottom: 50.0,
              right: 50.0,
              child: Text(
                'hi flutter',
                style: TextStyle(
                  fontSize: 36.0,
                  fontWeight: FontWeight.bold,
                  fontFamily: 'serif',
                  color: Colors.white,
                )
              ),
            )
          ],
        ),
      ),
    );
  }
}

// Demo_8_Stack/Alignment
// Stack/Alignment
class LayoutDemo8 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    var stack = Stack(
      alignment: Alignment.topLeft,
      children: <Widget>[
        //底部添加一个图像
        CircleAvatar(
          backgroundImage: AssetImage('images/pic.jpg'),
          radius: 100.0,
        ),
        //上面添加一个容器,容器里再放一段文本
        Container(
          decoration: BoxDecoration(
            color: Colors.black38,
          ),
          child: Text(
            '我是超级飞侠',
            style: TextStyle(
              fontSize: 22.0,
              fontWeight: FontWeight.bold,
              color: Colors.white
            ),
            ),
        )
      ],
    );

    return Scaffold(
      appBar: AppBar(
        title: Text('Stack 层叠布局示例'),
      ),
      body: Center(
        child: stack,
      ),
    );
  }
}



// Demo_7_FittedBox(缩放布局)
// FittedBox(缩放布局)
class LayoutDemo7 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('FittedBox缩放布局示例'),
      ),
      body: Container(
        color: Colors.grey,
        width: 250.0,
        height: 250.0,
        child: FittedBox(
          // 改变填充属性值会得到不同的效果--
          // none,fill,contain,cover,fitWidth,fitHeight,scaleDown
          fit: BoxFit.scaleDown,
          alignment: Alignment.topLeft,
          child: Container(
            color: Colors.deepOrange,
            child: Text('缩放比例'),
          ),
        ),
      ),
    );
  }
}

// Demo_6_Column(垂直布局)
// Column垂直布局
class LayoutDemo6 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('垂直布局示例'),
      ),
      body: Column(
        children: <Widget>[
          Text('Flutter'),
          Text('垂直布局'),
          Expanded(
            child: FittedBox(
              fit: BoxFit.contain,
              child: FlutterLogo(),
            ),
          )
        ],
      ),
    );
  }
}

// Demo_5_Row(水平布局)
// Row水平布局
class LayoutDemo5 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('水平布局示例'),
      ),
      body: Row(
        children: <Widget>[
          Expanded(
            child: Text(
              '左侧文本',
              textAlign: TextAlign.center,
              ),
          ),
          Expanded(
            child: Text(
              '中间文本',
              textAlign: TextAlign.center,
            ),
          ),
          Expanded(
            child: FittedBox(
              fit: BoxFit.contain,
              child: FlutterLogo(),
            ),
          ),
          Expanded(
            child: Text(
              '右边文本',
              textAlign: TextAlign.center,
            ),
          ),
        ],
      ),
    );
  }
}


// Demo_4_Align(对齐布局)
// Align对齐布局示例
class LayoutDemo4 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Align对齐布局示例'),
      ),
      body: Stack(
        children: <Widget>[
          //左上角
          Align(
            alignment: FractionalOffset(0.0, 0.0),
            child: Image.asset(
              'images/pic.jpg',
              width: 128.0,
              height: 128.0,
              ),
          ),
          //右上角
          Align(
            alignment: FractionalOffset(1.0, 0.0),
            child: Image.asset(
              'images/pic.jpg',
              width: 128.0,
              height: 128.0,
              ),
          ),
          //水平垂直方向居中
          Align(
            alignment: FractionalOffset.center,
            child: Image.asset(
              'images/pic.jpg',
              width: 128.0,
              height: 128.0,
            ),
          ),
           //左下角
          Align(
            alignment: FractionalOffset.bottomLeft,
            child: Image.asset(
              'images/pic.jpg',
              width: 128.0,
              height: 128.0,
            ),
          ),
           //右下角
          Align(
            alignment: FractionalOffset.bottomRight,
            child: Image.asset(
              'images/pic.jpg',
              width: 128.0,
              height: 128.0,
            ),
          ),
        ],
      ),
    );
  }
}


// Demo_3_Padding(填充布局)
// Padding填充布局示例
class LayoutDemo3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Padding填充布局示例'),
      ),
      body: Center(
        child: Container(
          width: 300.0,
          height: 300.0,
          padding: EdgeInsets.all(40.0),//容器上下左右设置为60
          decoration: BoxDecoration(
            color: Colors.white,
            border: Border.all(
              color: Colors.green,
              width: 8.0,
            ),
          ),
          child: Container(
            width: 200.0,
            height: 200.0,
            decoration: BoxDecoration(
              color: Colors.white,
              border: Border.all(
                color: Colors.blue,
                width: 8.0,
              )
            ),
            child: FlutterLogo(),
          ),
        ),
      ),
    );
  }
}


// Demo_2_Container(居中布局)
// Center居中布局示例
class LayoutDemo2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Center居中布局示例'),
      ),
      body: Center(
        child: Text(
          'Hello HOYO!',
          style: TextStyle(
            fontSize: 30.0
          ),
        ),
      ),
    );
  }
}

// Demo_1_Container(容器布局)
// Container容器布局示例
class LayoutDemo1 extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    // 返回一个Container 对象
    Widget container = Container(
      //添加装饰效果
      decoration: BoxDecoration(
        color: Colors.grey,
      ),
      //子元素指定为一个垂直水平嵌套布局的组件
      child: Column(
        children: <Widget>[
          Row(
            children: <Widget>[
              //使用Expanded防止内容溢出
              Expanded(
                child: Container(
                  width: 100.0, //修改此处的Width,样式不变化
                  height: 150.0,
                  //添加边框样式
                  decoration: BoxDecoration(
                    //上下左右边框设置为宽度为10.0,颜色为蓝灰色
                    border: Border.all(width: 10.0, color: Colors.blueGrey),
                    //上下左右边框弧度设置为8.0
                    borderRadius: 
                      const BorderRadius.all(const Radius.circular(8.0)),
                  ),
                  //上下左右增加边距
                  margin: const EdgeInsets.all(4.0),
                  //添加图片
                  child: Image.asset('images/pic.jpg'),
                ),
              ),
              Expanded(
                child: Container(
                  width: 150.0,
                  height: 150.0,
                  //添加边框样式
                  decoration: BoxDecoration(
                    //上下左右边框设置为宽度为10.0,颜色为蓝灰色
                    border: Border.all(width: 10.0, color: Colors.blueGrey),
                    //上下左右边框弧度设置为8.0
                    borderRadius: 
                      const BorderRadius.all(const Radius.circular(8.0)),
                  ),
                  //上下左右增加边距
                  margin: const EdgeInsets.all(4.0),
                  //添加图片
                  child: Image.asset('images/pic.jpg'),
                ),
              ),
            ],
          ),
          Row(
            children: <Widget>[
              //使用Expanded防止内容溢出
              Expanded(
                child: Container(
                  width: 150.0,
                  height: 150.0,
                  //添加边框样式
                  decoration: BoxDecoration(
                    //上下左右边框设置为宽度为10.0,颜色为蓝灰色
                    border: Border.all(width: 10.0, color: Colors.blueGrey),
                    //上下左右边框弧度设置为8.0
                    borderRadius: 
                      const BorderRadius.all(const Radius.circular(8.0)),
                  ),
                  //上下左右增加边距
                  margin: const EdgeInsets.all(4.0),
                  //添加图片
                  child: Image.asset('images/pic.jpg'),
                ),
              ),
              Expanded(
                child: Container(
                  width: 150.0,
                  height: 150.0,
                  //添加边框样式
                  decoration: BoxDecoration(
                    //上下左右边框设置为宽度为10.0,颜色为蓝灰色
                    border: Border.all(width: 10.0, color: Colors.blueGrey),
                    //上下左右边框弧度设置为8.0
                    borderRadius: 
                      const BorderRadius.all(const Radius.circular(8.0)),
                  ),
                  //上下左右增加边距
                  margin: const EdgeInsets.all(4.0),
                  //添加图片
                  child: Image.asset('images/pic.jpg'),
                ),
              ),
            ],
          ),
        ],
      ),
    );

    return Scaffold(
      appBar: AppBar(
        title: Text('Container 布局容器示例'),
      ),
      body: container,
    );
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容