Flutter第三章(Paddi...
版权声明:本⽂为作者原创书籍。转载请注明作者和出处,未经授权,严禁私⾃转载,侵权必
究
情感语录:侠之⼤者为国为民,如果做不了侠者也别轻易做⼩⼈,多⼀些包容,其实很多事没你想像地那么糟糕!
哈喽,⼤家好,欢迎来到本章节,上⼀章节我们讲了
Image组件
、
ListView组件
、
GridView组件
还记得吗?知识点回顾戳这⾥Fultter基础第⼆
章在前两章节的捯饬下我相信你已经爱上了Flutter或者逐渐开始喜欢了上了,学习都是枯燥的,贵在坚持,加油
本章简要:
1、内距组件
Paddiing
2、⽔平布局组件
Row
3、垂直布局组件
Column
4、权重布局组件
Expanded
5、层叠(帧)组件
Stack
6、纵横⽐组件
AspectRatio
7、卡⽚组件
Card
8、包裹组件
Wrap
⼀、Paddiing组件
在Android原⽣控件中都有padding属性,但是Flutter中很多Widget是没有padding属性。这个时候我们可以⽤Padding组件处理容
器与⼦元素之间的间距。
属性说明
paddingpadding值,EdgeIntss设置填充的值
child⼦组件
⼆、Row组件
Row⽔平布局组件其实理解也很简单,你可以看做是Android原⽣中LinearLayout布局控件属性为⽔平⽅向,或者说是⼀个横向的ListView控
件,说是横向的ListView控件到更为贴切,因为在Flutter中Row的⼦元素接收的是⼀个
List
,这也使得Row控件变得更加灵活易⽤,开
发中
Row
和
Column
使⽤频率是很⾼的。
属性说明
mainAxisAlignment主轴的排序⽅式
crossAxisAlignment次轴的排序⽅式
children组件⼦元素
lumn组件三、Column组件
Column组件的⽤法其实和Row是⼀模⼀样的,只是⼀个是控制⽔平⽅向的,⼀个是垂直⽅向,会了Row组件的使⽤,Column⾃然也就会使⽤
了。
属性说明
mainAxisAlignment主轴的排序⽅式
crossAxisAlignment次轴的排序⽅式
children组件⼦元素
四、Expanded组件
Expanded可以⽤在Row和Column布局中,其的⽬的就是控制⼦元素之间的权重⽐,这和在原⽣中LinearLayout的权重使⽤是⼀个道理。
属性说明
flex元素站整个⽗Row/Column的⽐例
child⼦元素
这上⾯的4个组件的属性并未全部列出,只是给出了常⽤的属性,在学习的同时,还是建议结合源码查看,只有对源码熟悉了学的才快嘛,通过上
⾯的简单介绍,也对这4个组件有了简单的了解,下⾯我现将这学到的这⼏个组件进⾏下练习,毕竟光说不练那都是假把式嘛,还是要实操的
O(∩_∩)O
import'package:flutter/';
voidmain()=>runApp(MyApp());
classMyAppextendsStatelessWidget{
@override
Widgetbuild(BuildContextcontext){
returnnewMaterialApp(
home:newScaffold(
appBar:AppBar(
title:Text("呆萌"),
),
body:ViewLayout()),
);
}
}
classViewLayoutextendsStatelessWidget{
@override
Widgetbuild(BuildContextcontext){
returnListView(
children:
Text(
"这是Paddiing的简单应⽤",
style:TextStyle(fontSize:18,color:angeAccent),
),
SizedBox(
height:10,
),
//⽤容器包装下⽅便观察
Container(
color:rple,
height:60,
child:Padding(
//可以通过fromLTRB分别设置左上右下的内距,也可以⽤all统⼀设置
padding:RB(0,10,0,10),
child:k(
'/data2/pic/246708144/',
fit:ght),
),
),
SizedBox(
SizedBox(
height:10,
),
Text(
"这是Row应⽤(横向布局)",
style:TextStyle(fontSize:18,color:angeAccent),
),
SizedBox(
height:10,
),
Row(
mainAxisAlignment:venly,
//spaceEvenly主轴的排列⽅式最为常见
crossAxisAlignment:,
//⽤的⽐较少
children:
IconWidget(,color:),
IconWidget(,color:),
IconWidget(_all,color:),
],
),
SizedBox(
height:5,
),
Text(
"这是Column应⽤(垂直布局)",
style:TextStyle(fontSize:18,color:angeAccent),
),
SizedBox(
height:5,
),
Column(
mainAxisAlignment:etween,
//spaceEvenly主轴的排列⽅式最为常见
crossAxisAlignment:,
//⽤的⽐较少
children:
IconWidget(,color:),
SizedBox(
height:5,
),
IconWidget(,color:),
SizedBox(
height:5,
),
IconWidget(_all,color:),
],
),
SizedBox(
height:5,
),
Text(
"这是Expanded应⽤权重(1:2:1)",
style:TextStyle(fontSize:18,color:angeAccent),
),
SizedBox(
height:5,
),
Row(
children:
Expanded(
flex:1,child:IconWidget(,color:)),
Expanded(
flex:2,
child:IconWidget(,color:),
),
Expanded(
flex:1,
child:IconWidget(_all,color:),
),
],
),
),
SizedBox(
height:10,
),
Text(
"这是Expanded应⽤权重(1:2)",
style:TextStyle(fontSize:18,color:angeAccent),
),
SizedBox(
height:10,
),
Row(
children:
Expanded(
flex:1,child:IconWidget(,color:)),
Expanded(
flex:2,
child:IconWidget(,color:),
),
],
),
],
);
}
}
//封装⼀个简单的Icon⽅便调度
classIconWidgetextendsStatelessWidget{
doublesize=32.0;
Colorcolor=;
IconDataicon;
IconWidget(,{,});
@override
Widgetbuild(BuildContextcontext){
returnContainer(
height:50.0,
width:50.0,
color:,
child:
Center(child:Icon(,size:,color:)),
);
}
}
上⾯代码的布局效果如下:
实例
读者在练习的时候尽量多⼿动写下,多尝试,⽐如我这⾥并没去细讲
Column
、
Row
中的
MainAxisAlignment
的属性以及效果,希望你在练习的时
候能⾃⼰尝试感受下。
五、Stack组件
Stack表⽰堆的意思,就是在该组件下放⼊的组件,会⼀层⼀层的累积,这样说理解起来可能有点抽象。想像⼀下,这就好⽐修房⼦,Stack就是
房⼦的地基,⽽新建的第⼀层盖在地基上,第⼆层则盖在第⼀层上。有过Android原⽣开发的同学应该很好能理解,它就相当于原⽣中
的
FrameLayout
控件。在Flutter中我们可以⽤Stack或者Stack结合
Align
或者Stack结合
Positiond
来实现页⾯的定位布局,Stack是定位
发⽣的容器,只有在Stack中,绝对定位的Widget才会⽣效
属性说明
alignment配置所有⼦元素的显⽰位置
children⼦组件
其中关键的属性就是children,除了⼏个样式控制的参数之外,通过children可以传⼊⼀个
List
,可以使列表⽤在Stack中进⾏绝对
定位。
5.1Align组件
Stack组件中结合Align组件可以控制每个⼦元素的显⽰位置,既实现绝对定位
属性说明
alignment配置所有⼦元素的显⽰位置
child⼦组件
⽆论是单独使⽤Stack或者结合Align使⽤,其中对元素位置控制都是通过
alignment
来指定的,下⾯我们来结合它的源码分析下:
///
///The[x]and[y]argumentsmustnotbenull.
constAlignment(this.x,this.y)
:asrt(x!=null),
asrt(y!=null);
///Thedistancefractioninthehorizontaldirection.
///
///of1.0
///arenotlimitedtothatrange;
///valueslessthan-1.0reprentpositionstotheleftoftheleftedge,
///andvaluesgreaterthan1.0reprentpositionstotherightoftheright
///edge.
finaldoublex;
///Thedistancefractionintheverticaldirection.
///
///of1.0
///arenotlimitedtothatrange;
///valueslessthan-1.0reprentpositionsabovethetop,andvalues
///greaterthan1.0reprentpositionsbelowthebottom.
finaldoubley;
@override
doubleget_x=>x;
@override
doubleget_start=>0.0;
@override
doubleget_y=>y;
///Thetopleftcorner.
staticconstAlignmenttopLeft=Alignment(-1.0,-1.0);
///Thecenterpointalongthetopedge.
staticconstAlignmenttopCenter=Alignment(0.0,-1.0);
///Thetoprightcorner.
staticconstAlignmenttopRight=Alignment(1.0,-1.0);
///Thecenterpointalongtheleftedge.
staticconstAlignmentcenterLeft=Alignment(-1.0,0.0);
///Thecenterpoint,bothhorizontallyandvertically.
staticconstAlignmentcenter=Alignment(0.0,0.0);
///Thecenterpointalongtherightedge.
staticconstAlignmentcenterRight=Alignment(1.0,0.0);
///Thebottomleftcorner.
staticconstAlignmentbottomLeft=Alignment(-1.0,1.0);
///Thecenterpointalongthebottomedge.
staticconstAlignmentbottomCenter=Alignment(0.0,1.0);
///Thebottomrightcorner.
staticconstAlignmentbottomRight=Alignment(1.0,1.0);
这段源码⼀⽬了然,⽐较简单,⾸先
Alignment
是⼀个没有⽆参构造函数的类,创建该对象时必须传⼊⾮
null
且是double类型的
x
、
y
值,否则
报错。接下来是对
x
、
y
值的描述,我们可以简单的理解为
x(⽔平⽅向)
的位置在当前容器的可见区域从左到右是(-1到1之间),超出该值范围,
既超出了该容器的边,既不可以见,
y(垂直⽅向)
同理,只是从上到下⽽已。最后源码中帮我列出了9种常⽤的位置常量⽅便我们使⽤。
5.2Positioned组件
Stack组件中结合Positioned组件也可以控制每个⼦元素的显⽰位置,在绝对定位中Positioned可能更适合我们的开发习惯:
属性说明
top⼦元素距离顶部的距离
bottom⼦元素距离底部的距离
left⼦元素距离左侧距离
right⼦元素距离右侧距离
child⼦组件
width⼦元素的宽度
height⼦元素的⾼度
下⾯我们从源码中去看下注释⽂档。
///Createsawidgetthatcontrolswhereachildofa[Stack]ispositioned.
///
///Onlytwooutofthethreehorizontalvalues([left],[right],
///[width]),andonlytwooutofthethreeverticalvalues([top],
///[bottom],[height]),ca,atleastoneof
///thethreemustbenull.
///
///Seealso:
///
///*[ional],whichspecifiesthewidget'shorizontal
///positionusing`start`and`end`ratherthan`left`and`right`.
///*[PositionedDirectional],whichissimilarto[ional]
///butadaptstotheambient[Directionality].
constPositioned({
Keykey,
,
,
,
,
,
,
@requiredWidgetchild,
}):asrt(left==null||right==null||width==null),
asrt(top==null||bottom==null||height==null),
super(key:key,child:child);
⼤致可以理解是在使⽤
width
的时候不能同时使⽤
left
和
right
,既不能同时出现这三个属性,否则报错,如果在使⽤
width
的同时⼜使⽤
了
left
或
right
,既分别表⽰⼦元素从
左边
或者
右边
开始对齐移动
left
或
right
个单位值。同理
height
、
top
、
bottom
三者的使⽤亦是如此。
rd组件六、Card组件
Card是卡⽚组件块,内容可以由⼤多数类型的Widget构成,Card具有圆⾓和阴影,这让它看起来有⽴体感。
属性说明
margin外边距
child⼦组件
ShapeCard的阴影效果,默认的阴影效果为圆⾓的长⽅形边。
七、AspectRatio组件
AspectRatio的作⽤是根据设置调整⼦元素child的宽⾼⽐,它⾸先会在布局限制条件允许的范围内尽可能的扩展,widget的⾼度是由宽度和
⽐率决定的,类似于BoxFit中的contain,按照固定⽐率去尽量占满区域。如果在满⾜所有限制条件过后⽆法找到⼀个可⾏的尺
⼨,AspectRatio最终将会去优先适应布局限制条件,⽽忽略所设置的⽐率。
属性说明
aspectRatio宽⾼⽐,最终可能不会根据这个值去布局,
具体则要看综合因素,外层是否允许按照这
种⽐率进⾏布局,这只是⼀个参考值
child⼦组件
该组件在理解上可能⽐较难,下⾯我们来看⼀个实例:
newContainer(
height:100,
child:AspectRatio(
aspectRatio:3.0/1.0,
child:Container(
color:,
),
))
⽰例代码是定义了⼀个⾼度为100的区域,内部AspectRatio⽐率设置为3,最终AspectRatio的宽是300,⾼是100的⼀个区域。
⼋、Wra⼋、Wrap组件
开篇第⼀个例⼦讲了Column或者Row+ExpandedWidget来实现flex布局,但是Row+Expanded的实现⽅式有个致命问题是⽆法⾃动
换⾏,⽽真正的flex布局是有⼀个wrap属性的,对于⼀⾏⽆法铺开的场景⾮常实⽤。Wrap组件可以实现流布局,单⾏的Wrap跟Row表现
⼏乎⼀致,单列的Wrap则跟Row表现⼏乎⼀致。但Row与Column都是单⾏单列的,Wrap则突破了这个限制,mainAxis上空间不⾜
时,则向crossAxis上去扩展显⽰。
///Createsawraplayout.
///
///Bydefault,thewraplayoutishorizontalandboththechildrenandthe
///runsarealignedtothestart.
///
///The[textDirection]argumentdefaultstotheambient[Directionality],if
///eisnoambientdirectionality,andatextdirectionisgoing
///tobenecessarytodecidewhichdirectiontolaythechildreninorto
///disambiguate`start`or`end`valuesforthemainorcrossaxis
///directions,the[textDirection]mustnotbenull.
Wrap({
Keykey,
ion=ntal,
ent=,
g=0.0,
gnment=,
cing=0.0,
xisAlignment=,
rection,
alDirection=,
List
}):super(key:key,children:children);
常⽤属性说明:
属性说明
direction主轴的⽅向,默认⽔平
alignment主轴的对其⽅式
spacing主轴⽅向上的间距
textDirection⽂本⽅向
verticalDirection定义了children摆放顺序,默认是down,见Flex相关属性介绍。
runAlignmentrun的对齐⽅式,可以理解为新的⾏或者列,如果是⽔平⽅向布局的话,
run可以理解为新的⼀⾏
runSpacingrun的间距
⼜讲了4个组件,加上开篇讲的4个组件本章节你已经掌握了8个常⽤的组件了,下⾯我们还是先对刚刚学到的4个组件来做个⼩的练习,加深下印
象。
import'package:flutter/';
voidmain()=>runApp(MyApp());
classMyAppextendsStatelessWidget{
@override
Widgetbuild(BuildContextcontext){
returnnewMaterialApp(
home:newScaffold(
appBar:AppBar(
title:Text("呆萌"),
),
body:ViewLayout()),
);
}
}
classViewLayoutextendsStatelessWidget{
@override
Widgetbuild(BuildContextcontext){
returnListView(
children:
Text(
"这是Stack的简单应⽤",
style:TextStyle(fontSize:18,color:),
),
SizedBox(
height:5,
),
//⽤容器包装下设置背景⾊⽅便观察
Container(
color:rple,
height:60,
child:Stack(
alignment:Alignment(-1,-1),//将⼦元素定位在左上,或者使⽤常量topLeft
children:
Container(
width:100,
height:40,
color:,
),
Text('你说什么?',style:TextStyle(fontSize:16,color:))
],
),
),
SizedBox(
height:5,
),
),
Text(
"这是Stack结合Align的应⽤",
style:TextStyle(fontSize:18,color:),
),
SizedBox(
height:5,
),
Container(
height:100,
width:300,
color:,
child:Stack(
children:
Align(
alignment:Alignment(1,0),//定位最右边,垂直居中
child:Icon(,size:30,color:),
),
Align(
alignment:,//定位在容器的中⼼位置
child:Icon(,size:30,color:),
),
Align(
alignment:Left,//定位在容器的左下
child:Icon(_unit,size:30,color:),
)
],
),
),
SizedBox(
height:5,
),
Text(
"这是Stack结合Positioned的应⽤",
style:TextStyle(fontSize:18,color:),
),
SizedBox(
height:5,
),
//⽤容器包装下设置背景⾊⽅便观察
Container(
color:rple,
height:60,
child:Stack(
children:
Positioned(
right:10,//让⼦元素从右边开始对齐
width:120,//指定宽度为120个单位
child:Icon(_alarm,size:30,color:),
),
Positioned(
bottom:0,//让⼦元素从底部开始对齐
left:100,
height:50,
child:Icon(,size:30,color:),
),
Positioned(
left:5,//让⼦元素从左边开始对齐
width:150,
child:Text('你很帅,你造吗?',
style:TextStyle(fontSize:16,color:)),
)
],
),
),
SizedBox(
height:5,
),
Text(
"这是Card应⽤",
style:TextStyle(fontSize:18,color:),
),
SizedBox(
SizedBox(
height:5,
),
Card(
margin:(5),
color:,
elevation:10,
//10个单位的阴影
shape:RoundedRectangleBorder(
borderRadius:(ar(14.0))),
//设置圆⾓
child:Column(
children:
ListTile(
title:Text("Mr.Z",style:TextStyle(fontSize:18)),
subtitle:Text("⼯程师",style:TextStyle(fontSize:14)),
),
ListTile(
title:Text("电话:xxxxx"),
),
],
),
),
SizedBox(
height:5,
),
Text(
"这是AspectRatio应⽤",
style:TextStyle(fontSize:18,color:angeAccent),
),
SizedBox(
height:5,
),
Container(
height:100,
child:AspectRatio(
aspectRatio:3.0/1.0,
child:Container(
color:,
),
)),
SizedBox(
height:5,
),
Text(
"这是Wrap应⽤",
style:TextStyle(fontSize:18,color:angeAccent),
),
SizedBox(
height:5,
),
Wrap(
spacing:10,
runSpacing:10,
direction:ntal,
alignment:venly,
children:
ButtonItem("盗墓笔记"),
ButtonItem("⿁吹灯"),
ButtonItem("桃花怪⼤战菊花侠"),
ButtonItem("⽆主之城"),
ButtonItem("琅琊榜"),
ButtonItem("仙剑奇侠传"),
ButtonItem("风云决"),
ButtonItem("哪吒"),
ButtonItem("⽞门⼤师"),
ButtonItem("废材兄弟"),
ButtonItem("爱情公寓"),
],
)
],
],
);
}
}
//封装⼀个简单的Button⽅便调度
classButtonItemextendsStatelessWidget{
finalStringtext;
constButtonItem(,{Keykey}):super(key:key);
@override
Widgetbuild(BuildContextcontext){
returnRaidButton(
child:Text(,style:TextStyle(color:),),
textColor:(context).cardColor,
onPresd:(){});
}
}
上述练习代码效果⼤致如下:
实例
本章实战:
由于本章讲述的组件相对较多但并不复杂,本章节实战环节跳过,但希望你在学习的时候多结合源码⼿动练习下,虽然不难但本章节的东西在开发
中是使⽤⾮常频繁的。
好了本章节就此结束,⼜到了说再见的时候了,如果你喜欢请留下你的⼩红星,你们的⽀持才是创作的动⼒,如有错误,请热⼼的你留⾔指正,谢
谢⼤家观看,下章再会O(∩_∩)O
本文发布于:2023-01-04 04:52:54,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/88715.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |