Flutter学习-单子布局Widget

Posted GY-93

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter学习-单子布局Widget相关的知识,希望对你有一定的参考价值。

1. 概述

单子布局组件的含义是其只有一个子组件,可以通过设置一些属性设置该子组件所在的位置信息等。
比较常用的单子布局组件有:Align、Center、Padding、Container。

2. Align

2.1 Align的对齐方式

我们前面经常使用的Center组件,他的子组件为什么可以居中显示? 在我们查看Center的源码之后,发现Center 继承自Align ,并且Center没有做任何其他的操作, 我们传递的参数,Center原封不动的传递给Align。

class Center extends Align {
  /// Creates a widget that centers its child.
  const Center({ Key? key, double? widthFactor, double? heightFactor, Widget? child })
    : super(key: key, widthFactor: widthFactor, heightFactor: heightFactor, child: child);
}

相当于使用Center等于使用Align,那么为什么在外层嵌套一个Align之后里面的子组件就可以居中,我们可以查看下Align的源码

const Align({
    Key? key,
    this.alignment = Alignment.center, // 对齐方式,默认居中对齐
    this.widthFactor, // 宽度因子,不设置的情况,会尽可能大
    this.heightFactor, // 高度因子,不设置的情况,会尽可能大
    Widget? child, // 要布局的子Widget
  }) 

由源码我们可以看出,Align组件总有一个属性alignment表示是对齐方式,并且有一个默认值.center,所以里面的子组件可以居中,Align 占据了我们整个屏幕的区域

那么我们在使用Align的时候,可以通过设置alignment的值,来控制子组件显示的位置

class GYHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Align(
      //alignment: Alignment.topLeft,
      alignment: Alignment(-1,-1),  //这两种方式都是可以的
      child: Icon(Icons.pets,size: 80,)
    );
  }
}
  • Align 显示的区域 中心点是 (0,0) 左上角是(-1,-1),右下角是(1,1)
    在这里插入图片描述

2.2 Align的区域大小控制

  • widthFactorheightFactor作用:
    • 因为子组件在父组件中的对齐方式必须有一个前提,就是父组件得知道自己的范围(宽度和高度)
    • 如果widthFactorheightFactor不设置,那么默认Align会尽可能的大(尽可能占据自己所在的父组件);
    • 我们也可以对他们进行设置,比如widthFactor设置为3,那么相对于Align的宽度是子组件跨度的3倍;
      在这里插入图片描述
class GYHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.orange,
      child: Align(
        alignment: Alignment.bottomRight,
        // alignment: Alignment(-1,-1),
        child: Icon(
          Icons.pets,   
          size: 80,
        ),
        widthFactor: 3,
        heightFactor: 4,
      ),
    );
  }
}

在这里插入图片描述

  • 注意: 如果外层的Container设置了自己的大小,那么widthFactorheightFactor这个两个属性设置是不起作用的
class GYHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 100,
      height: 100,
      color: Colors.orange,
      child: Align(
        alignment: Alignment.bottomRight,
        // alignment: Alignment(-1,-1),
        child: Icon(
          Icons.pets,
          size: 80,
        ),
        widthFactor: 3,
        heightFactor: 4,
      ),
    );
  }
}

在这里插入图片描述

2. Center

代码演练:

class GYHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.orange,
      child: Center(
        widthFactor: 2,
        heightFactor: 2,
        child: Icon(
          Icons.pets,
          size: 80,
        ),
      ),
    );
  }
}

在这里插入图片描述

3. Padding

Padding组件在其他端也是一个属性而已,但是在Flutter中是一个Widget,但是Flutter中没有Margin这样一个Widget,这是因为外边距也可以通过Padding来完成。
Padding通常用于设置子Widget到父Widget的边距(你可以称之为是父组件的内边距或子Widget的外边距)。

源码:

const Padding({
    Key? key,
    required this.padding,
    Widget? child,
  })

代码演练:

class GYHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(left: 20),
      child: Text(
        "padding",
        style: TextStyle(fontSize: 30, color: Colors.orange),
      ),
    );
  }
}

在这里插入图片描述

  • padding还有很多其他的用法,可以自行查看文档

4. Container

4.1 源码查看、基础演练

Container组件类似于其他android中的View,ios中的UIView。
如果你需要一个视图,有一个背景颜色、图像、有固定的尺寸、需要一个边框、圆角等效果,那么就可以使用Container组件。

源码:

Container({
    Key? key,
    this.alignment, //对齐方式
    this.padding,//容器内补白,属于decoration的装饰范围
    this.color,// 背景色
    this.decoration,// 背景装饰
    this.foregroundDecoration,//前景装饰
    double? width,//容器的宽度
    double? height,//容器的高度
    BoxConstraints? constraints,//容器大小的限制条件
    this.margin,//容器外补白,不属于decoration的装饰范围
    this.transform,
    this.transformAlignment,
    this.child,//变换
    this.clipBehavior = Clip.none,
  }) 

大多数属性在介绍其它容器时都已经介绍过了,不再赘述,但有两点需要说明:

  • 容器的大小可以通过widthheight属性来指定,也可以通过constraints来指定,如果同时存在时,widthheight优先。实际上Container内部会根据widthheight来生成一个constraints
  • colordecoration是互斥的,实际上,当指定color时,Container内会自动创建一个decoration
class GYHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Color.fromRGBO(5, 5, 20, 0.5),
      width: 100,
      height: 100,
      child: Icon(
        Icons.pets,
        size: 30,
      ),
    );
  }
}

4.2 BoxDecoration

Container有一个非常重要的属性 decoration

  • 他对应的类型是Decoration类型,但是它是一个抽象类。
  • 在开发中,我们经常使用它的实现类BoxDecoration来进行实例化

BoxDecoration的常见属性:

const BoxDecoration({
    this.color, //颜色,会和Container中的color属性冲突
    this.image, // 背景图片
    this.border,// 边框,对应类型是Border类型,里面每一个边框使用BorderSide
    this.borderRadius, // 圆角效果
    this.boxShadow,// 阴影效果
    this.gradient,// 渐变效果
    this.backgroundBlendMode,// 背景混合
    this.shape = BoxShape.rectangle,// 形变
  }) 

4.2.1 Color属性冲突

class GYHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromRGBO(5, 5, 20, 0.5),
        width: 100,
        height: 100,
        child: Icon(
          Icons.pets,
          size: 30,
        ),
        decoration: BoxDecoration(
          color: Colors.orange, 
        ),
      ),
    );
  }
}

在这里插入图片描述

其实我们查看源码便可以知道为什么会报错?

在这里插入图片描述

4.2.2 部分效果演示

class GYHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        // color: Color.fromRGBO(5, 5, 20, 0.5),
        width: 100,
        height: 100,
        child: Icon(
          Icons.pets,
          size: 30,
        ),
        decoration: BoxDecoration(
          color: Colors.orange,
          border: Border.all(
              color: Colors.redAccent, width: 3, style: BorderStyle.solid),
          borderRadius: BorderRadius.circular(5), //设置圆角 这里也可以使用only设置
          boxShadow: [
            BoxShadow(offset: Offset(5, 5), color: Colors.purple, blurRadius: 5)
          ],
          //          shape: BoxShape.circle, // 会和borderRadius冲突
          gradient:LinearGradient(colors: [Colors.orange,Colors.purple])//渐变效果
        ),
      ),
    );
  }
}

在这里插入图片描述

4.3 实现圆角图片

class GYHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //实现圆角图片
    return Center(
      child: Container(
        width: 100,
        height: 100,
        decoration: BoxDecoration(
          image: DecorationImage(
            image: NetworkImage(
                "https://tva1.sinaimg.cn/large/006y8mN6gy1g7aa03bmfpj3069069mx8.jpg"),
          ),
          color: Colors.orange,
          borderRadius: BorderRadius.circular(10), //设置圆角 这里也可以使用only设置
        ),
      ),
    );
  }
}

在这里插入图片描述

以上是关于Flutter学习-单子布局Widget的主要内容,如果未能解决你的问题,请参考以下文章

Flutter学习-多子布局Widget

Flutter 学习 布局类Widget

Flutter CustomSingleChildLayout 通用单子布局

Flutter学习笔记(22)--单个子元素的布局Widget(ContainerPaddingCenterAlignFittedBoxOffstageLimitedBoxOverflo

Flutter 学习 容器类Widget

flutter之布局Widget