使用Google Voice服务可以免费拨打美国或加拿大境内的任何电话,而国际电话(非北美地区)的费用也比传统电话便宜,比如拨打中国大陆的价格为1美分/分钟,香港的价格为2美分/分钟,台湾市话:2美...
Day 17 | Flutter的常用 widgets - Container、Row、Column
StatefulWidget 的build
回到昨天 StatefulWidget
的 build
会先看到 Scaffold
这个 widget ,这是一个Material 所提供的一个基本的排版widget,通常都会当作一个页面的开始,这里有用上三个参数 appBar
、 body
、 floatingActionButton
。
appBar
就是app最上方的工具列, 这里是用 AppBar
这个widget ,主要就是一些页面标题或者操作选单或回到上一页按钮会出现在这里,appBar
的型别是 PreferredSizeWidget
,所以其实只要是PreferredSizeWidget
都可以传进 appBar
也不一定要用AppBar
就是了。
然後是body
就是主要的显示区块,通常都会放置我们主要要操作及显示的Widgets。
floatingActionButton
则是那颗悬浮按钮通常会是那页最主要的操作,像是google导航的导航按钮就是做在这颗按钮。而他的位置预设会是右下角也可以使用其他参数来控制他的位置。
而body
里的 widget其实我们光是看命名也很好猜出他们的功能是什麽, Center
就是置中用、 Column
就是一个直行的容器, Text
就是放文字的。这里就能体会到 aggressive composability 的好处就是当每个功能/排版/容器都是一个widget时我们可以从命名就能知道他的作用是什麽,而缺点是等你开始组成一个复杂的layout你会发现这个深度会令人无法直视。
常用widget
就 flutter 官方上的 widget 列表的数量来说一个一个介绍显然不切实际,所以大概就只会简介一下常用的widget。
通常我在找我想用的widget时如果是没有比较复杂互动的widget的话,我倾向先去我 catalog 来查找,当然如果真的很复杂的功能就会去找第三方套件之类的。
所以我们来看一下这个 catalog 有哪些常用的widget。
基本上最最最常用的还是 Layout
这个分类的widget,在这个分类下有分成这三种widget。
Single-child layout widgets
接受widget的参数是 child
也就是只能传入单一个 widget 的 widget,像是 Container
、SizedBox
、Expanded
、 Padding
等等。
Multi-child layout widgets
接受widget的参数是 children
所以就是能传入 List<Widget>
,这类的有 Row
、 Column
、Stack
、 ListView
、 GirdView
等等。
Sliver widgets
可以自定义滚动效果的widget,但这部分我就没有实作就不额外说明了。
Container
而另外一个最常用的就是 Container
,基本上是可以想像成没有很自由的 div
在使用,大部分是拿来当作一个元件的基底widget,可以设定固定宽高及padding,可以使用 decoration
做额外的样式等等设定。
Container(
width: 300,
height: 300,
child: Text('这是一个高宽都是300px的Container'),
decoration: BoxDecoration(color: Colors.black26),
),
Row Column
在Flutter中的Row
、 Column
都是flex的所以如果有写过网页前端的读者应该能蛮容易理解Row、Column的排版逻辑。
基本上跟css中的flexBox的概念一样,会有两条轴与主轴方向平行一致就是Main Axis与之垂直就是Cross Axis。
所以在预设专案的这段中
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
Column
的 mainAxisAlignment
的意思是指在主轴上的对齐模式,所以以上面例子来看就是:对在主轴方向置中,也就是从画面上是垂直置中。
MainAxisAlignment
总共有几个值
MainAxisAlignment.start: 尽可能将children
向主轴起点放置
MainAxisAlignment.end: 尽可能将children
向主轴终点放置
MainAxisAlignment.center: 尽可能将children
向主轴中间放置
MainAxisAlignment.spaceBetween: 将剩余间距分散在各元素之间但第一个元素的前面及最後一个没有间距。
MainAxisAlignment.spaceAround: 将剩余间距分散在各元素之间但第一个元素的前面及最後一个没只有一半的间距。
MainAxisAlignment.spaceEvenly: 将间距平均分散在每个元素之间包含第一个元素的前面及最後一个元素後面
使用 Row
来排列的话,这三者的差异在画面上的差异是这样:
CrossAxisAlignment
则是垂直轴的排列方式:
CrossAxisAlignment.start:元素的开始位置是在垂直轴的起点
CrossAxisAlignment.end:元素的开始位置是在垂直轴的终点
CrossAxisAlignment.center:元素的开始位置是在垂直轴的中间
CrossAxisAlignment.stretch:将元素占满垂直轴
CrossAxisAlignment.baseline:将元素按照垂直轴的基准线排列(不常用)
以 Row
来说 CrossAxisAlignment.start 就是元素会贴着上面,CrossAxisAlignment.center就会是垂直置中。
Row及Column的要注意的一点是 「不能换行」 ,他们就是单纯的一条线,如果超出外面容器的宽度就会直接跳出错误。
这边是一个 Container
包着 Column
再包 Row
Container(
width: 300,
child: Column(
children: [
Text('这是一个宽度300px的Container'),
Row(
children: [
...List.generate(
5,
(_) => const Text('123456456'),
)
],
)
],
),
decoration: BoxDecoration(color: Colors.black26),
),
以这个例子来说通常是会将 Row
换成 Wrap
来达成换行的需求。
Container(
width: 300,
child: Column(
children: [
Text('这是一个宽度300px的Container'),
Wrap(
children: [
...List.generate(
5,
(_) => const Text('123456456'),
)
],
)
],
),
decoration: BoxDecoration(color: Colors.black26),
),
我个人是觉得会使用 Container
、Row
及 Column
就能完成一些很基础的排版需求了,剩下的等实际开发时遇到再来说明。
明天就来做我们第一个小专案也顺便开始真正的运用状态管理。
国内公司、香港公司、美国公司是目前绝大部分跨境卖家的身份选择。国内公司身份自然不必多说,90%+都是。香港和美国公司则少的多。但选择的人多并不表示国内公司就是最佳的经营跨境电商身份选择。 国内公司 首...
在深入探讨提高网站速度之前,让我们探讨一下为什么它对您的小型企业如此重要。 更快的网站意味着: 更好的用户体验 您的网站性能会影响用户的体验 - 当您的网站加载速度更快时,用户更有可能与之互动并花费更...
网站速度优化对于创造积极的用户体验至关重要。 积极的用户体验是快乐用户的营销代言词。 快乐的用户访问您的网站并购买东西。 不满意的用户离开是因为他们厌倦了等待您的网站加载。 营销人员称之为“跳出率”...
为什么网站速度很重要 到目前为止,您应该不需要说服网站速度对您的在线业务至关重要。 这是因为网站性能会影响您的品牌声誉、SEO 排名和转化率。 以下是发生这种情况的主要原因: 品牌口碑👍 老实说,当...