美文网首页
Flutter--SizedBox

Flutter--SizedBox

作者: UILabelkell | 来源:发表于2019-11-22 16:44 被阅读0次

    使用场景

    一般限制子控件大小

    还有这么一种场景也可以使用SizeBox,就是可以代替padding和container,然后 用来设置两个控件之间的间距,比如在行或列中就可以设置两个控件之间的间距 主要是可以比使用一个padding或者container简单方便 (在Flutter中可能用不同的控件可以实现到相同的目的,尽量使用越简单的widget来实现)

    SizedBox源码

    /// A box with a specified size。
    /// 意思就是一个指定大小的盒子,SizedBox会强制设置它的孩子的宽度或者高度为指定值。
    ///
    /// SizedBox的构造函数的参数:width,height, child。
    /// 如果width,height, child都指定的话,那SizedBox和child的宽度和高度都为指定值。
    /// 如果只指定width和child的话,那child的宽度为指定值,child的高度自适应,SizedBox的高度将跟child的高度一样。
    /// 如果只指定height和child的话,那child的高度为指定值,child的宽度自适应,SizedBox的宽度将跟child的宽度一样。
    /// 如果没有指定child,SizedBox的大小为指定的大小。
    ///
    /// [new SizedBox.expand]的构造方法可以使SizedBox的大小充满parent的布局,相当于设置了SizedBox
    /// 的宽度和高度为[double.infinity](无穷大)。
    class SizedBox extends SingleChildRenderObjectWidget {
      /// 创建一个SizedBox,参数[width]和[height] 可以为空,表示width或者height对应的方向不受约束,会自适应。
      const SizedBox({ Key key, this.width, this.height, Widget child })
        : super(key: key, child: child);
     
      /// 创建一个SizedBox,会去充满父布局
      const SizedBox.expand({ Key key, Widget child })
        : width = double.infinity,
          height = double.infinity,
          super(key: key, child: child);
     
      /// 创建一个SizeBox,尽可能地小。
      const SizedBox.shrink({ Key key, Widget child })
        : width = 0.0,
          height = 0.0,
          super(key: key, child: child);
     
      /// 创建一个指定Size的SizedBox。
      SizedBox.fromSize({ Key key, Widget child, Size size })
        : width = size?.width,
          height = size?.height,
          super(key: key, child: child);
     
      /// 如果width不为空,会要求它的child具有这个宽度
      final double width;
     
      /// 如果height不为空,会要求它的height具有这个高度
      final double height;
     
      @override
      RenderConstrainedBox createRenderObject(BuildContext context) {
        return RenderConstrainedBox(
          additionalConstraints: _additionalConstraints,
        );
      }
     
      BoxConstraints get _additionalConstraints {
        return BoxConstraints.tightFor(width: width, height: height);
      }
     
      @override
      void updateRenderObject(BuildContext context, RenderConstrainedBox renderObject) {
        renderObject.additionalConstraints = _additionalConstraints;
      }
     
      @override
      String toStringShort() {
        String type;
        if (width == double.infinity && height == double.infinity) {
          type = '$runtimeType.expand';
        } else if (width == 0.0 && height == 0.0) {
          type = '$runtimeType.shrink';
        } else {
          type = '$runtimeType';
        }
        return key == null ? '$type' : '$type-$key';
      }
     
      @override
      void debugFillProperties(DiagnosticPropertiesBuilder properties) {
        super.debugFillProperties(properties);
        DiagnosticLevel level;
        if ((width == double.infinity && height == double.infinity) ||
            (width == 0.0 && height == 0.0)) {
          level = DiagnosticLevel.hidden;
        } else {
          level = DiagnosticLevel.info;
        }
        properties.add(DoubleProperty('width', width, defaultValue: null, level: level));
        properties.add(DoubleProperty('height', height, defaultValue: null, level: level));
      }
    }
     
    /// ConstrainedBox是一个小部件,可以对它的child增加额外的约束。
    /// 例如,你想让child的最小高度为50.0,那么可以使用const BoxConstraints(minHeight: 50.0)作为[constraints]属性。
    class ConstrainedBox extends SingleChildRenderObjectWidget {
      /// 创建一个小部件,对它的孩子增加一些额外的约束
      ///
      /// [constraints]参数不能为空。
      ConstrainedBox({
        Key key,
        @required this.constraints,
        Widget child
      }) : assert(constraints != null),
           assert(constraints.debugAssertIsValid()),
           super(key: key, child: child);
     
      /// 对child增加的约束constraints
      final BoxConstraints constraints;
     
      @override
      RenderConstrainedBox createRenderObject(BuildContext context) {
        return RenderConstrainedBox(additionalConstraints: constraints);
      }
     
      @override
      void updateRenderObject(BuildContext context, RenderConstrainedBox renderObject) {
        renderObject.additionalConstraints = constraints;
      }
     
      @override
      void debugFillProperties(DiagnosticPropertiesBuilder properties) {
        super.debugFillProperties(properties);
        properties.add(DiagnosticsProperty<BoxConstraints>('constraints', constraints, showName: false));
      }
    }
     
     
    /// A widget that sizes its child to a fraction of the total available space.
    /// 一个小部件,会使它的子部件大小,调整为剩余可用空间的一部分,可以使用百分比
    /// See also:
    ///
    ///  * [Align], 根据子元素的大小,调整自己的大小,根据[Alignment]的参数值,调整子元素的位置。
    class FractionallySizedBox extends SingleChildRenderObjectWidget {
     
      ///  [widthFactor] and [heightFactor] 不能是负数。
      const FractionallySizedBox({
        Key key,
        this.alignment = Alignment.center,
        this.widthFactor,
        this.heightFactor,
        Widget child,
      }) : assert(alignment != null),
           assert(widthFactor == null || widthFactor >= 0.0),
           assert(heightFactor == null || heightFactor >= 0.0),
           super(key: key, child: child);
     
      /// If non-null, the fraction of the incoming width given to the child.
      ///
      /// If non-null, the child is given a tight width constraint that is the max
      /// incoming width constraint multiplied by this factor.
      ///
      /// If null, the incoming width constraints are passed to the child
      /// unmodified.
      final double widthFactor;
     
      /// If non-null, the fraction of the incoming height given to the child.
      ///
      /// If non-null, the child is given a tight height constraint that is the max
      /// incoming height constraint multiplied by this factor.
      ///
      /// If null, the incoming height constraints are passed to the child
      /// unmodified.
      final double heightFactor;
     
      /// 根据alignment对齐孩子,默认值为[Alignment.center]
      /// Alignment(this.x, this.y),利用x和y的值来控制水平方向和竖直方向的对齐。
      /// 比如x为 -1.0,表示child的左边缘和parent的左边缘对齐,x为1则表示child的右边缘和
      /// parent的右边缘对齐。
      /// x为0则表示child的中心和parent的中心对齐。
      /// 其他值利用线性插值的方法去计算。默认会有一些自定义的常量,比如Alignment.center表示(0,0)
      final AlignmentGeometry alignment;
     
      @override
      RenderFractionallySizedOverflowBox createRenderObject(BuildContext context) {
        return RenderFractionallySizedOverflowBox(
          alignment: alignment,
          widthFactor: widthFactor,
          heightFactor: heightFactor,
          textDirection: Directionality.of(context),
        );
      }
     
      @override
      void updateRenderObject(BuildContext context, RenderFractionallySizedOverflowBox renderObject) {
        renderObject
          ..alignment = alignment
          ..widthFactor = widthFactor
          ..heightFactor = heightFactor
          ..textDirection = Directionality.of(context);
      }
     
      @override
      void debugFillProperties(DiagnosticPropertiesBuilder properties) {
        super.debugFillProperties(properties);
        properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment));
        properties.add(DoubleProperty('widthFactor', widthFactor, defaultValue: null));
        properties.add(DoubleProperty('heightFactor', heightFactor, defaultValue: null));
      }
    }
     
    /// 一个可以限制子控件的最大宽高的控件。
    /// 如果LimtedBox本身控件的最大宽度是没有限制的话,那么它的child控件的最大宽度就是所设置的[maxWidth]。
    /// 如果LimtedBox本身控件的最大高度是没有限制的话,那么它的child控件的最大高度就是所设置的[maxHeight]。
    class LimitedBox extends SingleChildRenderObjectWidget {
      /// Creates a box that limits its size only when it's unconstrained.
      /// The [maxWidth] and [maxHeight] arguments must not be null and must not be
      /// negative.
      const LimitedBox({
        Key key,
        this.maxWidth = double.infinity,
        this.maxHeight = double.infinity,
        Widget child,
      }) : assert(maxWidth != null && maxWidth >= 0.0),
           assert(maxHeight != null && maxHeight >= 0.0),
           super(key: key, child: child);
      /// The maximum width limit to apply in the absence of a
      /// [BoxConstraints.maxWidth] constraint.
      final double maxWidth;
      /// The maximum height limit to apply in the absence of a
      /// [BoxConstraints.maxHeight] constraint.
      final double maxHeight;
      @override
      RenderLimitedBox createRenderObject(BuildContext context) {
        return RenderLimitedBox(
          maxWidth: maxWidth,
          maxHeight: maxHeight
        );
      }
      @override
      void updateRenderObject(BuildContext context, RenderLimitedBox renderObject) {
        renderObject
          ..maxWidth = maxWidth
          ..maxHeight = maxHeight;
      }
      @override
      void debugFillProperties(DiagnosticPropertiesBuilder properties) {
        super.debugFillProperties(properties);
        properties.add(DoubleProperty('maxWidth', maxWidth, defaultValue: double.infinity));
        properties.add(DoubleProperty('maxHeight', maxHeight, defaultValue: double.infinity));
      }
    }
    /// 一个小部件,OverflowBox允许它的child控件,溢出它的父控件,进行绘制,不会报OverFlow的错误。
    class OverflowBox extends SingleChildRenderObjectWidget {
      /// Creates a widget that lets its child overflow itself.
      const OverflowBox({
        Key key,
        this.alignment = Alignment.center,
        this.minWidth,
        this.maxWidth,
        this.minHeight,
        this.maxHeight,
        Widget child,
      }) : super(key: key, child: child);
      /// 跟上面的解释是一样的
      final AlignmentGeometry alignment;
      /// 设置child的最小宽度
      /// 如果为空,则默认是使用来自OverflowBox的父节点的约束
      final double minWidth;
      /// 设置child的最大宽度
      /// 如果为空,则默认是使用来自OverflowBox的父节点的约束
      final double maxWidth;
      /// 设置child的最小高度
      final double minHeight;
      ///设置child的最大高度
      final double maxHeight;
      @override
      RenderConstrainedOverflowBox createRenderObject(BuildContext context) {
        return RenderConstrainedOverflowBox(
          alignment: alignment,
          minWidth: minWidth,
          maxWidth: maxWidth,
          minHeight: minHeight,
          maxHeight: maxHeight,
          textDirection: Directionality.of(context),
        );
      }
      @override
      void updateRenderObject(BuildContext context, RenderConstrainedOverflowBox renderObject) {
        renderObject
          ..alignment = alignment
          ..minWidth = minWidth
          ..maxWidth = maxWidth
          ..minHeight = minHeight
          ..maxHeight = maxHeight
          ..textDirection = Directionality.of(context);
      }
      @override
      void debugFillProperties(DiagnosticPropertiesBuilder properties) {
        super.debugFillProperties(properties);
        properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment));
        properties.add(DoubleProperty('minWidth', minWidth, defaultValue: null));
        properties.add(DoubleProperty('maxWidth', maxWidth, defaultValue: null));
        properties.add(DoubleProperty('minHeight', minHeight, defaultValue: null));
        properties.add(DoubleProperty('maxHeight', maxHeight, defaultValue: null));
      }
    }
    /// 原理跟上面的OverflowBox差不多
    class SizedOverflowBox extends SingleChildRenderObjectWidget {
      /// Creates a widget of a given size that lets its child overflow.
      ///
      /// The [size] argument must not be null.
      const SizedOverflowBox({
        Key key,
        @required this.size,
        this.alignment = Alignment.center,
        Widget child,
      }) : assert(size != null),
           assert(alignment != null),
           super(key: key, child: child);
      final AlignmentGeometry alignment;
      /// The size this widget should attempt to be.
      final Size size;
      @override
      RenderSizedOverflowBox createRenderObject(BuildContext context) {
        return RenderSizedOverflowBox(
          alignment: alignment,
          requestedSize: size,
          textDirection: Directionality.of(context),
        );
      }
      @override
      void updateRenderObject(BuildContext context, RenderSizedOverflowBox renderObject) {
        renderObject
          ..alignment = alignment
          ..requestedSize = size
          ..textDirection = Directionality.of(context);
      }
      @override
      void debugFillProperties(DiagnosticPropertiesBuilder properties) {
        super.debugFillProperties(properties);
        properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment));
        properties.add(DiagnosticsProperty<Size>('size', size, defaultValue: null));
      }
    

    相关文章

      网友评论

          本文标题:Flutter--SizedBox

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