美文网首页
7. Flutter - 基础组件 之 布局Widget

7. Flutter - 基础组件 之 布局Widget

作者: Aliv丶Zz | 来源:发表于2021-03-17 11:13 被阅读0次

    1. Align组件

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

    文档中已经为我们定义了一些常量:如下

      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);
      /// The bottom right corner.
      static const Alignment bottomRight = Alignment(1.0, 1.0);
    

    centerAlignment(0.0, 0.0)topLeftAlignment(-1.0, -1.0),这些值均是以父视图为准进行的设置。父视图范围内取值为(-1.0, -1.0) ~ (1.0, 1.0),中心点为(0.0, 0.0)。当然我们也可以取值(0, 2),(3,0)等,这不过会超出父视图显示范围。

    widthFactor和heightFactor作用
    • 子组件在父组件中的对齐方式必须有一个前提,就是父组件得知道自己的范围(宽度和高度);
    • 如果widthFactor和heightFactor不设置,那么默认Align会尽可能的大(尽可能占据自己所在的父组件);
    • 我们也可以对他们进行设置,比如widthFactor设置为5,那么相对于Align的宽度是子组件跨度的5倍;
    • 代码演示:

    ps:Container为容器视图,主要为了设置背景色及大小,方便观察,后面会有介绍。

    class AlignTest extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            Container(
              margin: EdgeInsets.all(20),
              color: Colors.blue,
              child: Align(
                child: Icon(Icons.pets, size: 36, color: Colors.red),
                //左上
                alignment: Alignment(-1, -1),
                widthFactor: 5,
                heightFactor: 5,
              ),
            ),
            Container(
              padding: EdgeInsets.all(10),
              color: Colors.green,
              child: Align(
                child: Icon(Icons.pets, size: 36, color: Colors.red),
                //右下角
                alignment: Alignment(1, 1),
                widthFactor: 3,
                heightFactor: 3,
              ),
            )
          ],
        );
      }
    }
    
    • 显示效果:


      Align效果演示.png

    2. Center 组件

    class Center extends Align {
      const Center({ 
          Key key, 
          double widthFactor, 
          double heightFactor, 
          Widget child 
      }) : super(key: key, widthFactor: widthFactor, heightFactor: heightFactor, child: child);
    }
    

    Center组件继承自Align,只是将alignment设置为Alignment.center,且Alignalignment属性默认为 Alignment.center
    所以其实Align(alignment = Alignment.center)可以与 Center相互替换,效果是一样的。

    3. Padding组件

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

    • 代码演示:
    class PaddingTest extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          width: 300,
          height: 300,
          color: Colors.green,
          child: Padding(
            padding: EdgeInsets.all(20),
            child: Container(
                decoration: BoxDecoration(
                    color: Colors.blue,
                    border: Border.all(color: Colors.red, width: 3)),
                child: Text('测试')),
          ),
        );
      }
    }
    

    如下图,Padding的设置对于绿色视图,相当于内边距;而对于蓝色视图则是外边距。

    显示效果

    4. Container 组件

    Container组件类似于iOS中的UIView,主要负责视图的承载,可以通过它设置背景色、边框、圆角等等。

    Container({
      Key key,
      //AlignmentGeometry类型可选命名参数,容器内子Widget如何对其,使用其子类Alignment
      this.alignment,
      //EdgeInsetsGeometry类型可选命名参数,设置容器内边距
      this.padding,
      //Color类型可选命名参数,容器填充色
      Color color,
      //Decoration类型可选命名参数,绘制在child子Widget后面的装饰,使用BoxDecoration
      Decoration decoration,
      //Decoration类型可选命名参数,绘制在child子Widget前面的装饰,使用BoxDecoration
      this.foregroundDecoration,
      //double类型可选命名参数,容器的宽度
      double width,
      //double类型可选命名参数,容器的高度
      double height,
      //BoxConstraints类型可选命名参数,对child设置的Widget的约束
      BoxConstraints constraints,
      //EdgeInsetsGeometry类型可选命名参数,设置容器外边距
      this.margin,
      //Matrix4类型可选命名参数,在绘制容器之前要应用的转换矩阵
      this.transform,
      //Widget类型可选命名参数,容器包含的子Widget
      this.child,
    })
    

    容器的大小可以通过width、height属性来指定,也可以通过constraints来指定,如果同时存在时,width、height优先。实际上Container内部会根据width、height来生成一个constraints;
    colordecoration是互斥的,不可同时设置。

    • BoxDecoration

    Container有一个非常重要的属性 decoration,他对应的类型是Decoration类型,但是它是一个抽象类。
    在实际开发中,我们经常使用它的实现类BoxDecoration来进行实例化。

    const BoxDecoration({
      //Color类型可选命名参数,填充背景色
      this.color,
      //DecorationImage类型可选命名参数,在背景或渐变上绘制的图像
      this.image,
      //BoxBorder类型可选命名参数,边框设置
      this.border,
      //BorderRadiusGeometry类型可选命名参数,设置圆角
      this.borderRadius,
      //List<BoxShadow>类型可选命名参数,盒子后面的盒子投射的阴影列表
      this.boxShadow,
      //Gradient类型可选命名参数,填充框时使用的渐变
      this.gradient,
      //BlendMode类型可选命名参数,应用于框的颜色或渐变背景的混合模式
      this.backgroundBlendMode,
      //BoxShape类型可选命名参数,将背景颜色、渐变和图像填充到并作为boxShadow投射的形状
      this.shape = BoxShape.rectangle,
    })
    
    示例代码:
    class ContainerTest extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          // width: 400,
          // height: 400,
          padding: EdgeInsets.all(20),
    
          color: Colors.lightBlue,
          child: Container(
              width: 280,
              height: 280,
              //内边距
              // padding: EdgeInsets.all(100),
              //外边距
              // margin: EdgeInsets.all(80),
              // 不可与 decoration 同时设置
              // color: Colors.red,
              //变形:旋转
              transform: Matrix4.rotationZ(0.1),
              //装饰:设置颜色。渐变色、形状、阴影等。
              decoration: BoxDecoration(
                  color: Colors.green,
                  //渐变
                  gradient: LinearGradient(
                      colors: [Colors.blue, Colors.red, Colors.green]),
                  //形状
                  shape: BoxShape.circle,
                  //阴影
                  boxShadow: [
                    BoxShadow(offset: Offset(10, 10), color: Colors.grey)
                  ],
                  backgroundBlendMode: BlendMode.srcOver,
                  border: Border.all(color: Colors.orange, width: 5)),
              child: Icon(
                Icons.people,
                color: Colors.orange,
                size: 100,
              )),
        );
      }
    }
    
    显示效果.png

    5. Flex组件

    Row组件和Column组件都继承自Flex组件。
    Flex组件和Row、Column属性主要的区别就是多一个direction。
    direction的值为Axis.horizontal的时候,则是Row
    direction的值为Axis.vertical的时候,则是Column

    • 5.1 Row组件
     Row({
        Key key,
        //主轴对齐方式
        MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
        //主轴大小(水平方向尽可能大)
        MainAxisSize mainAxisSize = MainAxisSize.max,
        //    交叉处对齐方式
        CrossAxisAlignment crossAxisAlignment =  CrossAxisAlignment.center,
         //   水平方向子widget布局顺序
        TextDirection textDirection,
         //表示Row纵轴(垂直)的对齐方向
        VerticalDirection verticalDirection = VerticalDirection.down,
        //    如果上面是baseline对齐方式
        TextBaseline textBaseline = TextBaseline.alphabetic,
        // 子widget列表
        List<Widget> children = const <Widget>[],
      })
    
    • mainAxisSize:表示Row在主轴(水平)方向占用的空间,默认是MainAxisSize.max,Row的宽度始终等于水平方向的最大宽度
      MainAxisSize.min表示尽可能少的占用水平空间,Row的实际宽度等于所有子widgets占用的的水平空间;
    • mainAxisAlignment:表示子Widgets在Row所占用的水平空间内对齐方式
      如果mainAxisSize值为MainAxisSize.min,则此属性无意义,因为子widgets的宽度等于Row的宽度
      只有当mainAxisSize的值为MainAxisSize.max时,此属性才有意义
      MainAxisAlignment.start表示沿textDirection的初始方向对齐,
      如textDirection取值为TextDirection.ltr时,则MainAxisAlignment.start表示左对齐,textDirection取值为TextDirection.rtl时表示从右对齐。
      而MainAxisAlignment.end和MainAxisAlignment.start正好相反;
      MainAxisAlignment.center表示居中对齐。
    • crossAxisAlignment:表示子Widgets在纵轴方向的对齐方式
      Row的高度等于子Widgets中最高的子元素高度
      它的取值和MainAxisAlignment一样(包含start、end、 center三个值)
      不同的是crossAxisAlignment的参考系是verticalDirection,即verticalDirection值为VerticalDirection.down时crossAxisAlignment.start指顶部对齐,verticalDirection值为VerticalDirection.up时,crossAxisAlignment.start指底部对齐;而crossAxisAlignment.end和crossAxisAlignment.start正好相反;
    5.2 Column组件

    Column组件与 Row组件使用方式完全一致,只是方向不同而已。

    Column({
        Key key,
        MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
        MainAxisSize mainAxisSize = MainAxisSize.max,
        CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
        TextDirection textDirection,
        VerticalDirection verticalDirection = VerticalDirection.down,
        TextBaseline textBaseline,
        List<Widget> children = const <Widget>[],
      })
    

    相关文章

      网友评论

          本文标题:7. Flutter - 基础组件 之 布局Widget

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