minwidth

#标题创作挑战#

本文同步我的掘台原文翻译:https://juejin.cn/post/7108530957976043528.

minwidth

banner旗帜

需要了解颤振布局的案例吗?

在这里,我将展示我使用Flutter布局的代码片段。我将通过结合漂亮的代码片段和可视化图形来给出一个例子。

本文重点展示一些更有用的颤振部件,而不是一目了然地展示很多部件。

Row and Column

行列布局。

MainAxisAlignment

圆柱

row/*或Column */(mainaxis alignment:mainaxis alignment . start,children:& lt;Widget & gt,),复制代码行。

圆柱

row/*或Column */(mainaxis alignment:mainaxis alignment . center,children:& lt;Widget & gt,),复制代码行。

圆柱

row/*或Column */(mainaxis alignment:mainaxis alignment . end,children:& lt;Widget & gt,),复制代码行。

圆柱

row/*或Column */(mainaxis alignment:mainaxis alignment . space between,children:& lt;Widget & gt,),复制代码行。

圆柱

row/*或Column */(mainaxis alignment:mainaxis alignment . space equally,children:& lt;Widget & gt,),复制代码行。

圆柱

Row /*or Column*/( mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ Icon(Icons.star, size: 50), Icon(Icons.star, size: 50), Icon(Icons.star, size: 50), ],),复制代码CrossAxisAlignment

row/*或Column */(crosaxisalignment:crosaxisalignment . start,children:& lt;Widget & gt,),复制代码行。

圆柱

row/*或Column */(crosaxisalignment:crosaxisalignment . center,children:& lt;Widget & gt,),复制代码行。

圆柱

row/*或Column */(crosaxisalignment:crosaxisalignment . end,children:& lt;Widget & gt,),复制代码行。

圆柱

row/*或Column */(crosaxisalignment:crosaxisalignment . stretch,children:& lt;Widget & gt[图标(图标。星形,尺寸:50),图标(图标。星形,尺寸:200),图标(图标。star,size: 50),],),复制代码MainAxisSizeRow。

圆柱

row/*或Column */(maina xissize:maina xissize . max,children:& lt;Widget & gt,),复制代码行。

圆柱

row/*或Column */(maina xissize:maina xissize . min,children:& lt;Widget & gt[图标(图标。星形,尺寸:50),图标(图标。星形,尺寸:50),图标(图标。star,size: 50),],),复制代码固有宽度和固有高度在行和列的布局中,如何使所有的组件与宽度/高度最大的组件具有相同的宽度/高度?如下所示:

我们有以下布局:

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;IntrinsicWidth & # 39)),body:Center(child:Column(children:& lt;Widget & gt[ RaisedButton( onPressed: () {},child:Text(& # 39;Short & # 39),),RaisedButton( onPressed: () {},child:Text(& # 39;有点长& # 39;),),RaisedButton( onPressed: () {},child:Text(& # 39;最长的文本按钮& # 39;), ), ], ), ), );}复制代码,然后,如果您希望所有按钮都与最宽的按钮一样宽,请使用IntrinsicWidth:

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;IntrinsicWidth & # 39))、body:Center(child:IntrinsicWidth(child:Column(crosaxisalignment:crosaxisalignment . stretch,children:& lt;Widget & gt[ RaisedButton( onPressed: () {},child:Text(& # 39;Short & # 39),),RaisedButton( onPressed: () {},child:Text(& # 39;有点长& # 39;),),RaisedButton( onPressed: () {},child:Text(& # 39;最长的文本按钮& # 39;), ), ], ), ), ), );同理,如果你想让所有的部分都和最高的部分一样高,就需要结合IntrinsicHeight和Row来实现。

Stack

Stack非常适合小部件互相重叠。

Widget build(build context context){ Widget main = Scaffold(app bar:app bar(title:Text(& # 39;堆栈& # 39;)), );return Stack(fit:Stack fit . expand,children:& lt;Widget & gt[主页,横幅(消息:& # 34;Top Start & # 34,位置:BannerLocation.topStart,)横幅(消息:& # 34;顶端& # 34;,位置:BannerLocation.topEnd,)横幅(消息:& # 34;底部开始& # 34;,位置:BannerLocation.bottomStart,)横幅(消息:& # 34;底端& # 34;,位置:BannerLocation.bottomEnd,),],);}复制代码使用自己的部分,你需要把它们放在定位的部分。

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;堆栈& # 39;)),body: Stack( fit: StackFit.expand,children:& lt;Widget & gt[Material(color:colors . yellow accent),Positioned( top: 0,left: 0,child: Icon(Icons.star,size: 50),),Positioned( top: 340,left: 250,child: Icon(Icons.call,size: 50),),],);}复制代码如果不想猜测顶部/底部的值,可以使用LayoutBuilder小部件来检索它们的值。

小部件构建(BuildContext上下文){ const iconSize = 50返回脚手架(app bar:app bar(title:Text(& # 39;与LayoutBuilder堆叠& # 39;)),body:layout builder(builder:(context,constraints)= & gt;Stack( fit: StackFit.expand,children:& lt;Widget & gt[Material(color:colors . yellow accent),Positioned( top: 0,child: Icon(Icons.star,size: iconSize),),Positioned(top:constraints . max height-iconSize,left:constraints . maxwidth-iconSize,child: Icon(Icons.call,size: iconSize),),],),),);}复制代码ExpandedExpanded用Flex\\Flexbox布局,非常适合多项目分配空。

行(子级:& ltWidget & gt[Expanded(child:Container(decoration:const box decoration(color:colors . red),),flex: 3,)Expanded(child:Container(decoration:const box decoration(color:colors . green),),flex: 2,)Expanded(child:Container(decoration:const box decoration(color:colors)。blue),),Flex: 1),,],),默认复制ConstrainedBox的代码,很多部分尽量使用all 空,比如:

card(child:const Text(& # 39;你好世界!'),color: Colors.yellow,)和copy code ConstrainedBox允许小部件根据需要使用剩余的空房间。

constrained box(constraints:box constraints . expand(),child:const Card(child:const Text(& # 39;你好世界!'),color: Colors.yellow,,),使用BoxConstraints复制代码,可以指定一个小部件可以有多少空,可以指定最小/最大高度/宽度。

除非指定了值,否则BoxConstraints.expand使用无限量的空(即使用所有剩余的空间隔):

constrained box(constraints:box constraints . expand(height:300),child:const Card(child:const Text(& # 39;你好世界!'),color: Colors.yellow),,),复制的代码上面的写法相当于下面的写法:

constrained box(constraints:box constraints(min width:double . infinity,maxWidth: double.infinity,minHeight: 300,maxHeight: 300,),child:const Card(child:const Text(& # 39;你好世界!'),color: Colors.yellow,)复制代码Align有时候,很难将我们的小部件设置为正确的大小——比如,它们可以自由拉伸,但这并不是你想要的。

当你在Column中使用CrossAxisAlignment.stretch时,会出现上述现象,而你想要的是这个按钮不拉伸。

column(crosaxisalignment:crosaxisalignment . stretch,children:& lt;Widget & gt[Align(child:raised button(on pressed:(){ },child:const Text(& # 39;按钮& # 39;),),],),复制代码当你的widget不受你设置的约束限制时,那么你可以尝试用Align widget来包装它。

Container

容器是最常用的部件之一——它有以下优点:

Container as a layout tool

当您不指定容器的高度或宽度时,它会自动适应子部件的大小。

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;作为布局的容器& # 39;))、body:Container(color:colors . yellow accent、child:Text(& # 34;嗨& # 34;), ), );}复制代码如果要扩展容器以适合其父部件,请将double.infinity的值设置为属性的高度或宽度。

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;作为布局的容器& # 39;))、body:Container(height:double . infinity、width: double.infinity、color: Colors.yellowAccent、child:Text(& # 34;嗨& # 34;), ), );}复制代码容器作为装饰你可以用容器的color属性来改变它的背景色,但是也可以用decoration和foregroundDecoration来改变。有了这两个属性,就可以完全改变容器的外观,这一点我们后面会讲到。

Decotion总是在子属性之后,foregroundDecoration总是在子属性之后。(不一定是这种情况)

Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Container.decoration')), body: Container( height: double.infinity, width: double.infinity, decoration: BoxDecoration(color: Colors.yellowAccent), child: Text("Hi"), ), );}复制代码

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;Container.transform & # 39)),body: Container(高度:300,宽度:300,transform:matrix 4 . rotation z(pi/4),decoration: BoxDecoration(颜色:Colors.yellowAccent),child:Text(& # 34;嗨& # 34;,textAlign: TextAlign.center,),),);}复制代码boxdecotion通常用于改变容器部件的外观。

image: DecorationImage

图片作为背景:

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;image:decoration image & # 39;))、body:Center(child:Container(height:200,width: 200,decoration:box decoration(color:colors . yellow,image:decoration image(fit:box fit . fit width,image:network image(& # 39;https://flutter . dev/images/catalog-widget-placeholder . png & # 39;,//地址无效),),),),);}复制代码border: Border以指定容器边框的外观。

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;Border:Border & # 39;)),body: Center( child: Container(高:200,宽:200,装饰:BoxDecoration(颜色:Colors.yellow,border: Border.all(颜色:Colors.black,宽:3),),),);}复制代码borderRadius: BorderRadius使边框拐角变圆。

如果装饰中shape属性的值是BoxShape.circle,那么borderRadius将不起作用。

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;borderRadius:borderRadius & # 39;)),body: Center( child: Container(高:200,宽:200,decoration: BoxDecoration(颜色:Colors.yellow,border: Border.all(颜色:Colors.black,宽:3),borderRadius:borderRadius . all(radius . circular(18)),),),),);}复制代码形状:BoxShapeBoxDecoration可以是矩形/正方形,也可以是椭圆/圆形。

对于其他形状,可以使用ShapeDecoration代替BoxDecoration。

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;形状:箱形& # 39;)),body: Center( child: Container(高:200,宽:200,装饰:BoxDecoration(颜色:Colors.yellow,形状:BoxShape.circle,),),);}复制代码boxShadow: List给容器添加阴影。

该参数是一个列表。您可以指定多个不同的阴影并将它们组合起来。

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;box shadow:List & lt;BoxShadow & gt')),body: Center( child: Container(高:200,宽:200,decoration: BoxDecoration(颜色:Colors.yellow,box shadow:const[box shadow(blur radius:10),],),),),);}复制代码渐变有三种类型的渐变:LinearGradient、RadialGradient和SweepGradient。

Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('gradient: LinearGradient')), body: Center( child: Container( height: 200, width: 200, decoration: BoxDecoration( gradient: LinearGradient( colors: const [ Colors.red, Colors.blue, ], ), ), ), ), );}复制代码

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;backgroundBlendMode & # 39))、body: Center( child: Container(高:200,宽:200,foreground decoration:box decoration(backgroundBlendMode:blend mode . exclusion,gradient:linear gradient(colors:const[colors . red,Colors.blue,],)),child:image . network(& # 39;https://flutter . io/images/catalog-widget-placeholder . png & # 39;,//图片404),),);}复制代码backgroundBlendMode不仅影响其所在的容器。

BackgroundBlendMode更改容器及其下部树的内容的颜色。

下面的代码有一个父容器来绘制图像,然后有一个子容器来使用backgroundBlendMode,但是您仍然可以获得与以前相同的效果。

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;backgroundBlendMode & # 39))、body:Center(child:Container(decoration:box decoration(image:decoration image(image:network image(& # 39;https://flutter . io/images/catalog-widget-placeholder . png & # 39;,// 404),),),child: Container(高度:200,宽度:200,foreground decoration:box decoration(backgroundBlendMode:blend mode . exclusion,gradient:linear gradient(colors:const[colors . red,Colors.blue,],),),),),),);}复制带倒角边框的代码材料。

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;形状:BeveledRectangleBorder & # 39))、body:Center(child:Material(shape:const BeveledRectangleBorder(borderRadius:borderRadius . all(radius . circular(20))、side:border side(color:colors . black,width: 4))、color: Colors.yellow、child: Container( height: 200,width: 200,)、)、)));}复制代码SliversSliverFillRemaining即使没有足够的空,当你想将内容居中时,这部分也是不可替代的。

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;SliverFillRemaining & # 39))、body:CustomScrollView(slivers:[sliverfillsremaining(hasScrollBody:false,child:Column(mainAxisAlignment:mainAxisAlignment . center,children:const[FlutterLogo(size:200),Text(& # 39;这是一些应该居中的最长的文本& # 39;'连同logo & # 39,textAlign: TextAlign.center,),],),),],),);}复制代码如果中间没有足够的空空间,SliverFillRemaining就会变成可滚动。

如果不使用SliverFillRemaining,内容将溢出,如下所示:

Filling the remaining space

除了对内容居中有用之外,SliverFillRemaining还填充剩余视口的可用空空间。为此,这个小部件必须放在CustomScrollView中,并且必须是最后一个片段。

如果没有足够的空空格,这些部分将变成可滚动的。

widget build(build context context){ return Scaffold(app bar:app bar(title:Text(& # 39;SliverFillRemaining & # 39))、body:CustomScrollView(slivers:[sliver list(delegate:SliverChildListDelegate(const[list tile(title:Text(& # 39;第一项& # 39;))、ListTile(标题:正文(& # 39;第二项& # 39;))、ListTile(标题:正文(& # 39;第三项& # 39;))、ListTile(标题:正文(& # 39;第四项& # 39;)),]),),sliverfillreshold(hasScrollBody:false,child:Container(color:colors . yellow accent,child:Column(mainAxisAlignment:mainAxisAlignment . center,children:const[FlutterLogo(size:200),Text(& # 39;这是一些应该居中的最长的文本& # 39;'连同logo & # 39,textAlign: TextAlign.center,),],),),),],),),);}复制代码SizedBoxSizedBox是最简单但最常用的小部件之一。

SizedBox as ConstrainedBox

SizedBox的工作方式有点类似于ConstrainedBox。

sizedbox . expand(child:Card(child:Text(& # 39;你好世界!'),color: Colors.yellowAccent,)复制代码SizedBox作为填充当需要添加内边距和外边距时,可以选择填充或者容器小部件。但是,与添加Sizedbox相比,它们可能更长,可读性更差。

列(子列:& ltWidget & gt[图标(图标。星形,大小:50),常量大小的框(高度:100),图标(图标。星形,尺寸:50),图标(图标。star,size: 50),],),将代码SizedBox作为一个不可见的对象多次复制,你想设置一个

显示

隐藏

小部件构建(BuildContext上下文){ bool isVisible = true// true或false返回Scaffold(app bar:app bar(title:Text(& # 39;isVisible = $ isVisible & # 39),),body: isVisible?Icon(Icons.star,size: 150) : const SizedBox(),);}复制代码因为SizedBox有一个const构造函数,所以用const SizeBox()真的很便宜。一个更便宜的解决方案是使用不透明度小部件,并将其不透明度值更改为0.0。这种解决方案的缺点是给定的小部件是不可见的,但它仍然占用空。

SafeArea

在不同的平台上,有一些特定的区域,比如Android的状态栏或者iPhone X的刘海块,我们不应该在这些区域下绘制内容。

解决方案是使用SafeArea小部件。(以下截图显示SafeArea未使用/已使用。)

没有

随着

widget build(build context context){ return Material(color:colors . blue,child:safe area(child:sized box . expand(child:Card(color:colors . yellow accent),),));}复制代码已经验证过了,需要注意的是RaisedButton已经被ElevatedButton代替了,实际使用中需要注意。本文重点介绍其布局思路和技巧。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

发表回复

登录后才能评论