美文网首页
Flutter(3)-UI布局

Flutter(3)-UI布局

作者: BoxJing | 来源:发表于2019-09-26 09:12 被阅读0次

本篇文章主要讲解一下Flutter中的布局知识。

  • Alignment
  • Row
  • Column
  • Stack
  • AspectRatio

1. Alignment

把Alignment单独拿出来是因为在Container的布局有点繁琐,先从一个简单的代码看一下Container里面的alignment

class BoxRowDemo extends StatelessWidget {
  final TextStyle _textStyle = TextStyle(
    color: Colors.white,
    fontSize: 36.0,
  );
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.deepPurple,
//      alignment: Alignment(1.0,0.0),
      child: Text('一个阿狸',style: _textStyle,),
    );
  }
}

看到运行的效果图,想必已经大致知道了设个Alignment的的作用,Container的布局行为的先后顺序是这样的:

  1. 采用alignment
  2. 以child改变大小
  3. 用了width、height、constraints
  4. 适应父Widget
  5. 尽可能小

源码中可以看到Alignment的一些默认值:

  /// The top left corner.
  static const Alignment topLeft = Alignment(-1.0, -1.0);
  /// The center point along the top edge.
  static const Alignment topCenter = Alignment(0.0, -1.0);
  /// The top right corner.
  static const Alignment topRight = Alignment(1.0, -1.0);
  /// The center point along the left edge.
  static const Alignment centerLeft = Alignment(-1.0, 0.0);
  /// The center point, both horizontally and vertically.
  static const Alignment center = Alignment(0.0, 0.0);
  /// The center point along the right edge.
  static const Alignment centerRight = Alignment(1.0, 0.0);
  /// The bottom left corner.
  static const Alignment bottomLeft = Alignment(-1.0, 1.0);
  /// The center point along the bottom edge.
  static const Alignment bottomCenter = Alignment(0.0, 1.0);

2. Row

来直接看一个Row的简单代码,容器里放置3个不同大小的小容器:

class BoxRowDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.deepPurple,
      alignment: Alignment(0.0,0.0),
      child: Row(
        children: <Widget>[
          Container(
            color: Colors.red,
            width: 80,
            height: 80,
          ),
          Container(
            color: Colors.green,
            width: 60,
            height: 60,
          ),
          Container(
            color: Colors.blue,
            width: 100,
            height: 100,
          )
        ],
      ),
    );
  }
}

运行效果就跟我们预想的一样,是横向排列的。在这里有一个mainAxisAlignmentcrossAxisAlignment需要提一下,在RowColumn中有主轴和交叉轴这两个东西,这两个东西可以辅助我们更方便的布局,先来看个只有主轴mainAxisAlignment的代码:

class BoxRowDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.deepPurple,
      alignment: Alignment(0.0,0.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          Container(
            color: Colors.red,
            width: 80,
            height: 80,
          ),
          Container(
            color: Colors.green,
            width: 60,
            height: 60,
          ),
          Container(
            color: Colors.blue,
            width: 100,
            height: 100,
          )
        ],
      ),
    );
  }

看几个不同的主轴值运行效果图,图中白色线条和数字用来辅助解释,这样可以更直观的看到每个值的作用:


主轴的属性值有:

  • start :主方向的开始处对齐(Row对应x轴,Column对应y轴)
  • end :主方向的结束处对齐
  • center : 主方向的中间处对齐
  • spaceBetween : 主方向的剩余空间均匀分布在子项的中间
  • spaceAround : 所有子项均分主轴空间,子项周围留空
  • spaceEvenly : 主方向的剩余空间均匀分布在子项的中间和两头

交叉轴crossAxisAlignment我们就来个简单的示例:

class BoxRowDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.deepPurple,
      alignment: Alignment(0.0,0.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Container(
            color: Colors.red,
            width: 80,
            height: 80,
          ),
          Container(
            color: Colors.green,
            width: 60,
            height: 60,
          ),
          Container(
            color: Colors.blue,
            width: 100,
            height: 100,
          )
        ],
      ),
    );
  }

看下运行效果图:



交叉轴的枚举值有:

  • start : 交叉轴方向顶部对齐 (Row对应y轴,Column对应x轴)
  • end : 交叉轴方向底部对齐
  • center : 交叉轴方向中部对齐
  • stretch : 交叉轴方向直接拉伸填充
  • baseline : 这个需要和textbaseline一起配合生效,下面会来个示例
class BoxBaseLineDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      crossAxisAlignment: CrossAxisAlignment.baseline,
      textBaseline: TextBaseline.alphabetic,
      children: <Widget>[
        Container(
            child: Text(
              '足记',
              style: TextStyle(fontSize: 15),
            ),
            color: Colors.red,
            height:40,
        ),
        Container(
          child: Text(
            'Fotoplace',
            style: TextStyle(fontSize: 60),
          ),
          color: Colors.purple,
          height: 80,
        ),
        Container(
            child: Text(
              'Box',
              style: TextStyle(fontSize: 30),
            ),
            color: Colors.blue,
            height: 80,
        ),
      ],
    );
  }
}

看一下运行效果就非常直接的看到作用,方便的将文字底部对齐了:


还有一个Expanded来一个示例:
class BoxExpandedDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      crossAxisAlignment: CrossAxisAlignment.baseline,
      textBaseline: TextBaseline.alphabetic,
      children: <Widget>[
        Expanded(
          child: Container(
            child: Text(
              '足记',
              style: TextStyle(fontSize: 15),
            ),
            color: Colors.red,
            height:40,
          ),
        ),
        Expanded(
          child: Container(
            child: Text(
              'Fotoplace',
              style: TextStyle(fontSize: 60),
            ),
            color: Colors.purple,
//            height: 80,
          ),
        ),
        Expanded(
          child: Container(
            child: Text(
              'Box',
              style: TextStyle(fontSize: 30),
            ),
            color: Colors.blue,
            height: 80,
          ),
        ),
      ],
    );
  }
}

看一下运行效果:


如果用Expanded也就意味着主轴方向不会有空余空间,一定会被子项分完,也有部分Expanded,部分非Expanded的子项,大家可以自行尝试尝试。

3. Column

上面的Row说清楚之后,Column就相对来说很简单了直接上个代码,改改值,自己看看效果就可以了:

class BoxColumnDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.deepPurple,
      alignment: Alignment(0.0,0.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Container(
            color: Colors.red,
            width: 80,
            height: 80,
          ),
          Container(
            color: Colors.green,
            width: 60,
            height: 60,
          ),
          Container(
            color: Colors.blue,
            width: 100,
            height: 100,
          )
        ],
      ),
    );
  }
}

4. Stack

Stack布局适合重叠式布局,来个带有位置Positioned的Stack布局示例:

class BoxStackDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Positioned(
          child: Container(
            color: Colors.red,
            width: 200,
            height: 200,
          ),
        ),
        Positioned(
          right: 0,
          child: Container(
            color: Colors.green,
            width: 100,
            height: 100,
          ),
        ),
        Positioned(
          left: 10,
          top: 30,
          child: Container(
            color: Colors.blue,
            width: 50,
            height: 50,
          ),
        ),
      ],
    );
  }
}

看一下运行结果,你会发现跟iOS中frame甚至只autolayout非常的像,在Stack布局中Positioned是经常会被用到的一个组件:

5. AspectRatio

AspectRatio主要用来设置一个比例,来一个示例看一下:

class BoxAspectRatioDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
        color: Colors.purple,
        alignment: Alignment(0.0,0.0),
        child: Container(
          color: Colors.blue,
          width: 168,
          child: AspectRatio(
            aspectRatio: 1/1,
            child: Icon(Icons.add,),
          ),
        )
    );
  }
}

可以方便的设置子项的一个比例大小,在根据屏幕大小的布局中会用得到。

无论在Flutter中的布局还是其他的布局,这个东西不是一篇文章就能够说的清楚的,这里只是简答的写了些基本的作用,我们在后面的不断开发中会不停的练习,用这些基本的布局完成美工高规格要求的UI。所有的代码都可以在Github:BoxJ/Flutter-daydayup中下载,本篇代码的文件夹是boxdemo_003,欢迎一起交流!

相关文章

  • Flutter(3)-UI布局

    本篇文章主要讲解一下Flutter中的布局知识。 Alignment Row Column Stack Aspec...

  • flutter:全局 context 在 navigator 与

    引言:什么是 context flutter 中的概念 '万物皆 widget '。flutter 的UI布局由一...

  • Flutter入门知识—声明式UI

    重点: 1、Flutter采用了声明式UI的布局方式,什么是声明式UI? 2、声明式UI和命令式UI的异同? Fl...

  • Flutter开发-仿携程项目

    Flutter是一个UI框架,其最重要的一块就是布局,就像官网所说的那样:"Flutter 布局的核心机制是 wi...

  • 声明式 UI

    Flutter 采用了声明式 UI 布局方式。 为什么是声明式 UI 从 Win32 到 Web 再到 Andro...

  • Flutter UI布局方式

    Flutter采用声明式UI布局方式 为什么是声明式UI 从win32到web再到Android和iOS的框架通常...

  • Flutter 学习

    1、布局绘制Flutter 布局[https://book.flutterchina.club/chapter3/...

  • 拖拽生成flutter代码工具

    新手对flutter布局不熟悉,可以上这个地址:https://ui.flutterdart.cn/ 通过拖拽代码...

  • Flutter 布局

    Flutter 布局详解 Flutter 布局(一)- Container详解 Flutter 布局(二)- Pa...

  • Flutter:适配学习

    flutter 屏幕适配方案,让你的UI在不同尺寸的屏幕上都能显示合理的布局! Flutter的适配可以使用flu...

网友评论

      本文标题:Flutter(3)-UI布局

      本文链接:https://www.haomeiwen.com/subject/qmtjyctx.html