irpas技术客

Flutter布局指南之Box套盒子_eclipse_xu

网络投稿 5115

点击上方蓝字关注我,知识会给你力量

对于写过Flutter的开发者来说,我敢肯定,大部分的开发者都不能准确预测这次Hot Reload之后,布局是否是自己想要的结果。Flutter的布局与Native的布局方式非常不同,所以,了解Flutter这茫茫多的布局组件,是我们准确布局的基础。

在Flutter中,有一堆Box布局组件,它们可以用来更加精确的调整布局,下面我们就来看看这些Box都有哪些作用。

ConstrainedBox

ConstrainedBox用于限制Child Widget的尺寸约束,例如:

让Text最宽100,从而实现多行

固定Widget最大最小尺寸

body:?Center( ??child:?Column( ????mainAxisAlignment:?MainAxisAlignment.center, ????children:?[ ??????ConstrainedBox( ????????constraints:?const?BoxConstraints( ??????????maxWidth:?100, ????????), ????????child:?const?Text( ??????????'xuyisheng', ??????????textAlign:?TextAlign.center, ??????????style:?TextStyle( ????????????fontSize:?50, ??????????), ????????), ??????), ??????ConstrainedBox( ????????constraints:?const?BoxConstraints( ??????????minHeight:?100, ????????), ????????child:?ElevatedButton( ??????????child:?const?Text('Flutter'), ??????????onPressed:?()?{}, ????????), ??????), ????], ??), )

效果如图所示。

image-20220227100216133 UnconstrainedBox

UnconstrainedBox的作用正好和ConstrainedBox相反。它可以破除组件本身的约束规则,从而更方便的进行布局。

例如下面这个例子:

Center( ??child:?Container( ????color:?Colors.blue, ????width:?300, ????height:?300, ????child:?Container( ??????width:?100, ??????height:?100, ??????color:?Colors.red, ????), ??), )

由于Container的布局规则,内部的Container被设置为父Widget尺寸,从而忽略了子Widget的尺寸设置,所以,这里使用UnconstrainedBox来解除这种约束:

Center( ??child:?Container( ????color:?Colors.blue, ????width:?300, ????height:?300, ????child:?UnconstrainedBox( ??????child:?Container( ????????width:?100, ????????height:?100, ????????color:?Colors.red, ??????), ????), ??), )

从而可以让内部的Container按照自身尺寸进行布局。

image-20220227134310007

更加灵活一点,我们还可以选择保留某一方向上的约束:constrainedAxis: Axis.horizontal。

SizedBox

SizedBox有下面几个使用场景:

当你需要一个确切尺寸的Widget时,通过SizedBox来进行约束

在父容器中撑满剩余空间

在没有child的情况下,对空间做分割

场景1:

SizedBox( ??width:?200, ??height:?200, ??child:?Text( ????'xuyisheng', ????textAlign:?TextAlign.center, ????style:?TextStyle( ??????fontSize:?50, ????), ??), )

场景2:某方向上的double.infinity,会在父级允许的尺寸下尽可能多的拓展。

Center( ??child:?Container( ????color:?Colors.red, ????width:?200, ????height:?200, ????child:?Center( ??????child:?Container( ????????color:?Colors.blue, ????????child:?const?SizedBox( ??????????width:?double.infinity, ??????????height:?100, ??????????child:?Text( ????????????'xuyisheng', ????????????textAlign:?TextAlign.center, ????????????style:?TextStyle( ??????????????fontSize:?50, ????????????), ??????????), ????????), ??????), ????), ??), )

展示效果如图所示。

image-20220227100133091

如果width和height方向上都是撑满父Widget的剩余空间,那么可以使用SizedBox.expand来简写。

还有一个便捷方法——SizedBox.shrink,它的作用是让尺寸在父容器的约束下尽可能的小,如果父容器不设置minWidth或者minHeight,那么它的尺寸就是0,这个属性通常和BoxConstraints一起配合使用。

FractionallySizedBox

这是Flutter给你提供的一个百分百布局工具。通常用于在父容器中,按照百分比来进行布局。

Center( ??child:?Container( ????color:?Colors.red, ????width:?200, ????height:?200, ????child:?const?FractionallySizedBox( ??????widthFactor:?0.5, ??????heightFactor:?0.5, ??????child:?Text( ????????'xuyisheng', ????????textAlign:?TextAlign.center, ????????style:?TextStyle( ??????????fontSize:?50, ????????), ??????), ????), ??), )

展示效果如图所示。

image-20220227104718092

和SizedBox一样,它也可以用于作为Widget直接的间隔,只不过它使用的是百分比作为单位,总量是父容器的尺寸。

如果使用Flexible组件包裹FractionallySizedBox,那么就可以适用于Row和Column。

要注意的是,widthFactor和heightFactor是可以大于1的,也就是说,子Widget可以超出父容器展示。

LimitedBox

当Widget没有父级来限制它们的尺寸时,如何在Widget上设置它的默认大小呢?这就需要使用到LimitedBox了。

LimitedBox只在父容器没有提供尺寸约束时,对子Widget的尺寸进行默认约束,在在Listview和Column、Row中是非常有用的。

?

如果外部容器对Child设置了尺寸约束,那么LimitedBox将不会生效

?

例如下面这个场景:

ListView( ??children:?[ ????for?(var?i?=?0;?i?<?100;?i++) ??????Container( ????????margin:?const?EdgeInsets.all(8), ????????color:?Colors.green, ??????), ??], )

由于Listview中无尺寸约束,所以Container是不会展示出来的,这时候就需要使用LimitedBox。

ListView( ??children:?[ ????for?(var?i?=?0;?i?<?100;?i++) ??????LimitedBox( ????????maxHeight:?100, ????????child:?Container( ??????????margin:?const?EdgeInsets.all(8), ??????????color:?Colors.green, ????????), ??????), ??], )

一句话总结LimitedBox的作用:在不受限制的环境中,为其子元素提供默认尺寸。

FittedBox

在Flutter中,Widget之间可以任意堆叠、嵌套,所以,当子Widget的尺寸与父Widget尺寸不一致时,就会产生一些奇怪的样式,FittedBox就是用来处理这种场景的。

Center( ??child:?Container( ????width:?200, ????height:?200, ????color:?Colors.red, ????child:?Text( ??????'xuyishengxuyisheng', ??????style:?TextStyle( ????????fontSize:?50, ??????), ????), ??), )

效果如图所示。

image-20220227111546196

Text会因为父容器尺寸的限制而自动换行,下面我们给它加上FittedBox。

Center( ??child:?Container( ????width:?200, ????height:?200, ????color:?Colors.red, ????child:?FittedBox( ??????child:?Text( ????????'xuyishengxuyisheng', ????????style:?TextStyle( ??????????fontSize:?50, ????????), ??????), ????), ??), )

效果如图所示。

image-20220227111859060

可以发现,FittedBox默认的fit是contain,所以内容被完整的一行显示了,与FontSize无关,这个就可以很方便的自适应修改文字大小。

当然,你还可以设置别的fit方式,详细的可以参考Flutter Dojo中的例子。fit属性是非常有用的一个属性,例如当我们设置FittedBox后,文字会在设备中自动显示为一行,但是在横竖屏切换时,Text会自动修改字体大小,来适配contain的效果,如果你想让它保存当前的文字Size,那么可以设置Fit为scaleDown,这样的话,它就会以最小尺寸来进行适配,当空间足够的时候,就不会自动放大字体大小了。

FittedBox中还可以设置alignment,从而控制剩余空间中子Widget的对齐方式。

简而言之,FittedBox就是一个让Child可以适配Parent的组件。

Flexible

准确来说,Flexible不算是Box类布局容器,但它和Box布局方式息息相关,所以这里一起说了。

Flexible通常在Column或者Row中使用,借助Flexible,可以让Column和Row中的元素根据Flex比例进行布局。

Column( ??children:?[ ????Flexible( ??????flex:?3, ??????child:?Container( ????????color:?Colors.cyan, ??????), ????), ????Flexible( ??????flex:?2, ??????child:?Container( ????????color:?Colors.green, ??????), ????), ????Flexible( ??????flex:?1, ??????child:?Container( ????????color:?Colors.purple, ??????), ????), ??], )

同时,当子Widget有尺寸约束时,可以使用fit属性来控制Flex选择怎样的约束,如果是FlexFit.tight,那么Flexible将严格按照Flex布局,而忽略子Widget的尺寸约束,如果是FlexFit.loose,则会将尺寸设置为子Widget的尺寸。

OverflowBox

对于Flutter的子父Widget来说,子Widget一般都是限制于父Widget的尺寸约束之下,但如果一定要让子Widget超过父Widget的渲染区域,那么就可以通过OverflowBox来实现。

Container( ??color:?Colors.blue, ??width:?200, ??height:?200, ??padding:?const?EdgeInsets.all(12.0), ??child:?OverflowBox( ????alignment:?Alignment.topLeft, ????maxWidth:?300.0, ????maxHeight:?500.0, ????child:?Container( ??????color:?Colors.red, ??????width:?400.0, ??????height:?400.0, ????), ??), )

效果如图所示。

image-20220227133208234

向大家推荐下我的网站?https://xuyisheng.top/??点击原文一键直达

专注 Android-Kotlin-Flutter 欢迎大家访问

往期推荐

Flutter布局指南之谁动了我的Key

FlutterComponent最佳实践之Shadow怎么就这么简单

FlutterComponent最佳实践之色彩管理

Flutter布局指南之深入理解BoxConstraints

本文原创公众号:群英传,授权转载请联系微信(Tomcat_xu),授权后,请在原创发表24小时后转载。

< END >

作者:徐宜生

更文不易,点个“三连”支持一下👇


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #Flutter #盒子 #Flutter的布局与N