小菜鸡开始学习flutter之二十三

71 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第23天,点击查看活动详情

今日目标

今天主要学习了解flutter中常见的页面布局组件Pading``Row``Column``Expanded,毕竟写页面是离不开这些的,所有有必要的了解一下。

Padding

在html中常见的布局标签都有padding属性,但是flutter中很多Widget是没有padding属性的,这个时候我们可以使用Padding组件处理容器与子元素之间的间距

组件属性

属性说明
paddingpadding值,EdgeInests设置填充的值
child子组件
class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return GridView.count(
      crossAxisCount: 2,
      childAspectRatio: 1,
      children: [
        Padding(
          padding: EdgeInsets.all(10.0),
          child:  Image.network(
            'https://p9-passport.byteacctimg.com/img/user-avatar/c21cdb224f42c072c2bb55075c9adf8d~300x300.image'),
        ),
        Padding(
          padding: EdgeInsets.all(10.0),
          child:  Image.network(
            'https://p3-passport.byteacctimg.com/img/user-avatar/5d08c09da9bffd1331bc6220b884a466~300x300.image'),
        ),
        Padding(
          padding: EdgeInsets.all(10.0),
          child:  Image.network(
            'https://p9-passport.byteacctimg.com/img/user-avatar/e3a142ceef01d6d640ac417a16f127f6~300x300.image'),
        ),
        Padding(
          padding: EdgeInsets.all(10.0),
          child:  Image.network(
            'https://p3-passport.byteacctimg.com/img/user-avatar/805b8f70cfa821ad44f66953346ad2b6~300x300.image'),
        ),
        Padding(
          padding: EdgeInsets.all(10.0),
          child:  Image.network(
            'https://p9-passport.byteacctimg.com/img/user-avatar/c21cdb224f42c072c2bb55075c9adf8d~300x300.image'),
        ),
        Padding(
          padding: EdgeInsets.all(10.0),
          child:  Image.network(
            'https://p3-passport.byteacctimg.com/img/user-avatar/5d08c09da9bffd1331bc6220b884a466~300x300.image'),
        ),
        Padding(
          padding: EdgeInsets.all(10.0),
          child:  Image.network(
            'https://p9-passport.byteacctimg.com/img/user-avatar/e3a142ceef01d6d640ac417a16f127f6~300x300.image'),
        ),
        Padding(
          padding: EdgeInsets.all(10.0),
          child:  Image.network(
            'https://p3-passport.byteacctimg.com/img/user-avatar/805b8f70cfa821ad44f66953346ad2b6~300x300.image'),
        ),
      ],
    );
  }
}

image.png
如上我们就给图片都添加了边距。

Row

Row是水平布局组件

组件属性

属性说明
mainAsixAlignment主轴的排序方式
crossAxisAlignment次轴的排序方式
children组件子元素集合
class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 500,
      width: 400.0,
      color: Colors.pink,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          IconContainer(Icons.home, color: Colors.blue),
          IconContainer(Icons.search, color: Colors.red),
          IconContainer(Icons.usb_rounded, color: Colors.green)
        ],
      ),
    );
  }
}

class IconContainer extends StatelessWidget {
  double? size = 32.0;
  Color? color = Colors.red;
  IconData icon;
  IconContainer(this.icon, {this.color, this.size});

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 100,
      width: 100,
      color: this.color,
      child: Center(
        child: Icon(
          this.icon,
          size: this.size,
          color: Colors.white,
        ),
      ),
    );
  }
}

image.png
要注意crossAxisAlignment是搭配外层组件使用的,表示这一行居于外层组件的什么位置。

Column

column是垂直布局组件

组件属性

属性说明
mainAsixAlignment主轴的排序方式
crossAxisAlignment次轴的排序方式
children组件子元素集合
class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      height: 500,
      width: 400.0,
      color: Colors.pink,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          IconContainer(Icons.home, color: Colors.blue),
          IconContainer(Icons.search, color: Colors.red),
          IconContainer(Icons.usb_rounded, color: Colors.green)
        ],
      ),
    );
  }
}

image.png
我们把Row替换成Column就得到了纵向的布局页面

expanded

expanded有点类似于web中的flex布局,可以用在Row和Column布局中

组件属性

属性说明
flex元素占整个父(Row/Column)的比例
child子元素
class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Row(
      children: [
        Expanded(child: IconContainer(Icons.home, color: Colors.blue),flex: 1,),
        Expanded(child: IconContainer(Icons.search, color: Colors.red),flex: 2,),
        Expanded(child: IconContainer(Icons.usb_rounded, color: Colors.green),flex: 1,)
      ],
    );
  }
}

image.png
有没有像我们平时写的双飞翼布局的感觉

小练习

image.png
学习了上面几种布局方式后,我们基本可以动手写一些复杂的布局了,接下来练习一下,大家可以尝试写一下图片中的布局结构再往下看。

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Padding(
      padding: EdgeInsets.all(10.0),
      child: Column(
        children: [
          Container(
            height: 100,
            decoration: BoxDecoration(
                color: Colors.black,
                borderRadius: BorderRadius.all(Radius.circular(5))),
          ),
          Padding(
            padding: EdgeInsets.fromLTRB(0, 10, 0, 0),
            child: Row(
              children: [
                Expanded(
                  child: Image.network(
                    'https://p3-passport.byteacctimg.com/img/user-avatar/805b8f70cfa821ad44f66953346ad2b6~300x300.image',
                    height: 100.0,
                    fit: BoxFit.cover,
                  ),
                  flex: 1,
                ),
                Container(
                  padding: EdgeInsets.fromLTRB(10, 0, 0, 0),
                  height: 100.0,
                  width: 150.0,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Image.network(
                        'https://p9-passport.byteacctimg.com/img/user-avatar/c21cdb224f42c072c2bb55075c9adf8d~300x300.image',
                        height: 45,
                        width: 150,
                        fit: BoxFit.cover,
                      ),
                      Image.network(
                        'https://p9-passport.byteacctimg.com/img/user-avatar/e3a142ceef01d6d640ac417a16f127f6~300x300.image',
                        height: 45,
                        width: 150,
                        fit: BoxFit.cover,
                      )
                    ],
                  ),
                )
              ],
            ),
          )
        ],
      ),
    );
  }
}

image.png
当然实现的方式不只有上面这一种写法,还可以更多的使用Expanded来实现自适应。
至此我们就能掌握基本的布局需求,一些我们正式项目中的布局方式大多数都可以写出来了。因为没有像css那样的样式表述写法,所以我们在flutter布局的时候要有一个整体的规划概念,毕竟套娃要修改还是有点难受的~~

ending

持续学习,如有不对的地方还请指正~~