Open SmallStoneSK opened 5 years ago
请问issue怎么下载啊,为什么不用仓库管理啊
请问issue怎么下载啊,为什么不用仓库管理啊
下载什么?没懂什么意思。。。
sta已点,真厉害,期待更新文章,跟着学习
文章写的真好,基础 widget 的介绍基本面面俱到,👍。
关于 Stack 想补充说一下它的 fit
属性,因为自己学习的时候有着重理解了一下。
fit
:用于定义没有定位的(non-positioned)子 widget 如何去适应 Stack 的大小,默认为 loose
。
其中 StackFit
有如下几种:
loose
:子节点宽松的取值,可以从min到max的尺寸;
expand
:子节点尽可能的占用空间,取max尺寸;
passthrough
:不改变子节点的约束条件;
具体效果可以在 @SmallStoneSK 提供的例子中改变属性值看看区别,也可以自己写个 Stack
的 demo。
另外这篇文章对 Stack
的属性都有示例效果,可以看下。
@w4mxl 哈哈,多谢补充~
前端高手,请教一个问题,如何在同一个页面里上下放2个LISTVIEW哈?
前端高手,请教一个问题,如何在同一个页面里上下放2个LISTVIEW哈?
@boybian 可以通过CustomScrollView
配合SliverList
使用,使用方式可以参考这篇文章
1. 前言
Flutter
作为时下最流行的技术之一,凭借其出色的性能以及抹平多端的差异优势,早已引起大批技术爱好者的关注,甚至一些闲鱼
,美团
,腾讯
等大公司均已开始使用。虽然目前其生态还没有完全成熟,但身靠背后的Google
加持,其发展速度已经足够惊人,可以预见将来对Flutter
开发人员的需求也会随之增长。无论是为了现在的技术尝鲜还是将来的潮流趋势,都9102年了,作为一个前端开发者,似乎没有理由不去尝试它。正是带着这样的心理,笔者也开始学习
Flutter
,同时建了一个用于练习的仓库,后续所有代码都会托管在上面,欢迎star,一起学习。今天分享的是Flutter中最常用到的一些基础组件,它们是构成UI界面的基础元素:
容器
,行
,列
,绝对定位布局
,文本
,图片
和图标
等。2. 基础组件
2.1 Container(容器组件)
Container
组件是最常用的布局组件之一,可以认为它是web开发中的div
,rn开发中的View
。其往往可以用来控制大小、背景颜色、边框、阴影、内外边距和内容排列方式等。我们先来看下其构造函数:2.1.1
width
,height
,margin
,padding
这些属性的含义和我们已经熟知的并没有区别。唯一需要注意的是,
margin
和padding
的赋值不是一个简单的数字,因为其有left
,top
,right
,bottom
四个方向的值需要设置。Flutter
提供了EdgeInsets
这个类,帮助我们方便地生成四个方向的值。通常情况下,我们可能会用到EdgeInsets
的4种构造方法:EdgeInsets.all(value)
: 用于设置4个方向一样的值;EdgeInsets.only(left: val1, top: val2, right: val3, bottom: val4)
: 可以单独设置某个方向的值;EdgeInsets.symmetric(horizontal: val1, vertical: val2)
: 用于设置水平/垂直方向上的值;EdgeInsets.fromLTRB(left, top, right, bottom)
: 按照左上右下的顺序设置4个方向的值。2.1.2
color
该属性的含义是背景颜色,等同于web/rn中的backgroundColor。需要注意的是
Flutter
中有一个专门表示颜色的Color
类,而非我们常用的字符串。不过我们可以非常轻松地进行转换,举个栗子:在web/rn中我们会用
'#FF0000'
或'red'
来表示红色,而在Flutter中,我们可以用Color(0xFFFF0000)
或Colors.red
来表示。2.1.3
alignment
该属性是用来决定
Container
组件的子组件将以何种方式进行排列(PS:再也不用为怎么居中操心了)。其可选值通常会用到:Alignment.topLeft
: 左上Alignment.topCenter
: 上中Alignment.topRight
: 右上Alignment.centerLeft
: 左中Alignment.center
: 居中Alignment.centerRight
: 右中Alignment.bottomLeft
: 左下Alignment.bottomCenter
: 下中Alignment.bottomRight
: 右下2.1.4
constraints
在web/rn中我们通常会用
minWidth
/maxWidth
/minHeight
/maxHeight
等属性来限制容器的宽高。在Flutter
中,你需要使用BoxConstraints
(盒约束)来实现该功能。2.1.5
decoration
该属性非常强大,字面意思是装饰,因为通过它你可以设置
边框
,阴影
,渐变
,圆角
等常用属性。BoxDecoration
继承自Decoration
类,因此我们通常会生成一个BoxDecoration
实例来设置这些属性。1) 边框
可以用
Border.all
构造函数直接生成4条边框,也可以用Border
构造函数单独设置不同方向上的边框。不过令人惊讶的是官方提供的边框竟然不支持虚线
(issue在这里)。2) 阴影
阴影属性和web中的
boxShadow
几乎没有区别,可以指定x
,y
,blur
,spread
,color
等属性。3) 渐变
如果你不想容器的背景颜色是单调的,可以尝试用
gradient
属性。Flutter
同时支持线性渐变
和径向渐变
:4) 圆角
通常情况下,你可能会用到
BorderRadius.circular
构造函数来同时设置4个角的圆角,或是BorderRadius.only
构造函数来单独设置某几个角的圆角:2.1.6
transform
transform
属性和我们在web/rn中经常用到的基本也没有差别,主要包括:平移
,缩放
、旋转
和倾斜
。在Flutter中,封装了矩阵变换类Matrix4
帮助我们进行变换:translationValues(x, y, z)
: 平移x, y, z;rotationX(radians)
: x轴旋转radians弧度;rotationY(radians)
: y轴旋转radians弧度;rotationZ(radians)
: z轴旋转radians弧度;skew(alpha, beta)
: x轴倾斜alpha度,y轴倾斜beta度;skewX(alpha)
: x轴倾斜alpha度;skewY(beta)
: y轴倾斜beta度;2.1.7 小结
Container
组件的属性很丰富,虽然有些用法上和web/rn有些许差异,但基本上大同小异,所以过渡起来也不会有什么障碍。另外,由于Container
组件是单子节点组件,也就是只允许子节点有一个。所以在布局上,很多时候我们会用Row
和Column
组件进行行
/列
布局。2.2 Row/Column(行/列组件)
Row
和Column
组件其实和web/rn中的Flex布局
(弹性盒子)特别相似,或者我们可以就这么理解。使用Flex布局
的同学对主轴
和次轴
的概念肯定都已经十分熟悉,Row
组件的主轴就是横向,Column
组件的主轴就是纵向。且它们的构造函数十分相似(已省略不常用属性):2.2.1
mainAxisAlignment
该属性的含义是主轴排列方式,根据上述构造函数可以知道
Row
和Column
组件在主轴方向上默认都是从start开始,也就是说Row
组件默认从左到右开始排列子组件,Column
组件默认从上到下开始排列子组件。当然,你还可以使用其他的可选值:
2.2.2
crossAxisAlignment
该属性的含义是次轴排列方式,根据上述构造函数可以知道
Row
和Column
组件在次轴方向上默认都是居中。这里有一点需要特别注意:由于
Column
组件次轴方向上(即水平)默认是居中对齐,所以水平方向上不会撑满其父容器,此时需要指定CrossAxisAlignment.stretch
才可以。另外,crossAxisAlignment其他的可选值有:
2.2.3
mainAxisSize
字面意思上来说,该属性指的是在主轴上的尺寸。其实就是指在主轴方向上,是包裹其内容,还是撑满其父容器。它的可选值有
MainAxisSize.min
和MainAxisSize.max
。由于其默认值都是MainAxisSize.max
,所以主轴方向上默认大小都是尽可能撑满父容器的。2.2.4 小结
由于
Row
/Column
组件和我们熟悉的Flex布局
非常相似,所以上手起来非常容易,几乎零学习成本。2.3 Stack/Positoned(绝对定位布局组件)
绝对定位布局在web/rn开发中也是使用频率较高的一种布局方式,
Flutter
也提供了相应的组件实现,需要将Stack
和Positioned
组件搭配在一起使用。比如下方的这个例子就是创建了一个黄色的盒子,并且在其四个角落放置了4个红色的小正方形。Stack
组件就是绝对定位的容器,Positioned
组件通过left
,top
,right
,bottom
四个方向上的属性值来决定其在父容器中的位置。2.4 Text(文本组件)
Text
组件也是日常开发中最常用的基础组件之一,我们通常用它来展示文本信息。来看下其构造函数(已省略不常用属性):data
: 显示的文本信息;style
: 文本样式,Flutter
提供了一个TextStyle
类,最常用的fontSize
,fontWeight
,color
,backgroundColor
和shadows
等属性都是通过它设置的;textAlign
: 文字对齐方式,常用可选值有TextAlign
的left
,right
,center
和justify
;softWrap
: 文字是否换行;overflow
: 当文字溢出的时候,以何种方式处理(默认直接截断)。可选值有TextOverflow
的clip
,fade
,ellipsis
和visible
;maxLines
: 当文字超过最大行数还没显示完的时候,就会根据overflow
属性决定如何截断处理。Flutter
的Text
组件足够灵活,提供了各种属性让我们定制,不过一般情况下,我们更多地只需下方几行代码就足够了:除了上述的应用场景外,有时我们还会遇到
富文本
的需求(即一段文本中,可能需要不同的字体样式)。比如在一些UI设计中经常会遇到表示价格的时候,¥
符号比金额
的字号小点。对于此类需求,我们可以用Flutter
提供的Text.rich
构造函数来创建相应的文本组件:2.5 Image(图片组件)
Image
图片组件作为丰富内容的基础组件之一,日常开发中的使用频率也非常高。看下其构造函数(已省略不常用属性):image
: 图片源,最常用到主要有两种(AssetImage
和NetworkImage
)。使用AssetImage
之前,需要在pubspec.yaml
文件中声明好图片资源,然后才能使用;而NextworkImage
指定图片的网络地址即可,主要是在加载一些网络图片时会用到;width
: 图片宽度;height
: 图片高度;color
: 图片的背景颜色,当网络图片未加载完毕之前,会显示该背景颜色;fit
: 当我们希望图片根据容器大小进行适配而不是指定固定的宽高值时,可以通过该属性来实现。其可选值有BoxFit
的fill
,contain
,cover
,fitWidth
,fitHeight
,none
和scaleDown
;repeat
: 决定当图片实际大小不足指定大小时是否使用重复效果。另外,
Flutter
还提供了Image.network
和Image.asset
构造函数,其实是语法糖。比如下方的两段代码结果是完全一样的:2.6
Icon
(图标组件)Icon
图标组件相比于图片有着放大不会失真的优势,在日常开发中也是经常会被用到。Flutter
更是直接内置了一套Material
风格的图标(你可以在这里预览所有的图标类型)。看下构造函数:icon
: 图标类型;size
: 图标大小;color
: 图标颜色。3. 布局实战
通过上一节的介绍,我们对
Container
,Row
,Column
,Stack
,Positioned
,Text
,Image
和Icon
组件有了初步的认识。接下来,就让我们通过一个实际的例子来加深理解和记忆。3.1 准备工作 - 数据类型
根据上述卡片中的内容,我们可以定义一些字段。为了规范开发流程,我们先给卡片定义一个数据类型的类,这样在后续的开发过程中也能更好地对数据进行Mock和管理:
3.2 搭建骨架,布局拆分
根据给的视觉图,我们可以将整体进行拆分,一共划分成4个部分:
Cover
,UserInfo
,PublishContent
和InteractionArea
。为此,我们可以搭起代码的基本骨架:3.3 封面区域
为了更好的凸现图片的效果,这里加了一个蒙层,所以此处刚好可以用得上
Stack
/Positioned
布局和LinearGradient
渐变,Dom结构如下:3.4 用户信息区域
用户信息区域就非常适合使用
Row
和Column
组件来进行布局,Dom结构如下:3.5 发布内容区域
通过这块区域的UI练习,我们可以实践
Container
组件设置不同的borderRadius
,以及Text
组件文本内容超出时的截断处理,Dom结构如下:3.6 互动区域
在这个模块,我们会用到
Icon
图标组件,可以控制其大小和颜色等属性,Dom结构如下:3.7 小结
通过上面的一个例子,我们成功地把一个看起来复杂的UI界面一步步拆解,将之前提到的组件都用了个遍,并且最终得到了不错的效果。其实,日常开发中90%以上的需求都离不开上述提到的基础组件。因此,只要稍加练习,熟悉了
Flutter
中的基础组件用法,就已经算是迈出了一大步哦~这里还有银行卡和朋友圈的UI练习例子,由于篇幅原因就不贴代码了,可以去github仓库看。
4. 总结
本文首先介绍了
Flutter
中构建UI界面最常用的基础组件(容器
,行
,列
,绝对定位布局
,文本
,图片
和图标
)用法。接着,介绍了一个较复杂的UI实战例子。通过对Dom结构的层层拆解,前文提到过的组件得到一个综合运用,也算是巩固了前面所学的概念知识。不过最后不得不吐槽一句:
Flutter
的嵌套真的很难受。。。如果不对UI布局进行模块拆分,那绝对是噩梦般的体验。而且不像web/rn开发样式可以单独抽离,Flutter
这种将样式当做属性的处理方式,一眼看去真的很难理清dom结构,对于新接手代码的开发人员而言,需要费点时间理解。。。