使用场景
一般限制子控件大小
还有这么一种场景也可以使用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));
}
网友评论