Day 17 | Flutter的常用 widgets - Container、Row、Column

   


StatefulWidget 的build

回到昨天 StatefulWidget 的 build

https://ithelp.ithome.com.tw/upload/images/20210930/20112906GVWMdP32Cx.png

会先看到 Scaffold 这个 widget ,这是一个Material 所提供的一个基本的排版widget,通常都会当作一个页面的开始,这里有用上三个参数 appBarbodyfloatingActionButton

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,像是 ContainerSizedBoxExpandedPadding 等等。

Multi-child layout widgets

接受widget的参数是 children 所以就是能传入 List<Widget> ,这类的有 RowColumnStackListViewGirdView 等等。

Sliver widgets

可以自定义滚动效果的widget,但这部分我就没有实作就不额外说明了。

Container

而另外一个最常用的就是 Container ,基本上是可以想像成没有很自由的 div 在使用,大部分是拿来当作一个元件的基底widget,可以设定固定宽高及padding,可以使用 decoration 做额外的样式等等设定。

Container(
	width: 300,
  height: 300,
  child: Text('这是一个高宽都是300px的Container'),
  decoration: BoxDecoration(color: Colors.black26),
),

https://ithelp.ithome.com.tw/upload/images/20210930/20112906vubUXjiz1F.png

Row Column

在Flutter中的RowColumn 都是flex的所以如果有写过网页前端的读者应该能蛮容易理解Row、Column的排版逻辑。

基本上跟css中的flexBox的概念一样,会有两条轴与主轴方向平行一致就是Main Axis与之垂直就是Cross Axis。

https://ithelp.ithome.com.tw/upload/images/20210930/201129068DZrat0xwX.png
https://ithelp.ithome.com.tw/upload/images/20210930/20112906BSoPWAN9gL.png

所以在预设专案的这段中

 Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        const Text(
          'You have pushed the button this many times:',
        ),
        Text(
        '$_counter',
        style: Theme.of(context).textTheme.headline4,
        ),
      ],
    ),

ColumnmainAxisAlignment 的意思是指在主轴上的对齐模式,所以以上面例子来看就是:对在主轴方向置中,也就是从画面上是垂直置中。

MainAxisAlignment 总共有几个值

MainAxisAlignment.start: 尽可能将children向主轴起点放置

MainAxisAlignment.end: 尽可能将children向主轴终点放置

MainAxisAlignment.center: 尽可能将children向主轴中间放置

MainAxisAlignment.spaceBetween: 将剩余间距分散在各元素之间但第一个元素的前面及最後一个没有间距。

MainAxisAlignment.spaceAround: 将剩余间距分散在各元素之间但第一个元素的前面及最後一个没只有一半的间距。

MainAxisAlignment.spaceEvenly: 将间距平均分散在每个元素之间包含第一个元素的前面及最後一个元素後面

使用 Row 来排列的话,这三者的差异在画面上的差异是这样:

https://ithelp.ithome.com.tw/upload/images/20210930/20112906aM4Ba2PVKP.png

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),
),
    

https://ithelp.ithome.com.tw/upload/images/20210930/201129066daptvvxb4.png

以这个例子来说通常是会将 Row 换成 Wrap 来达成换行的需求。

Container(
  width: 300,
  child: Column(
  children: [
	  Text('这是一个宽度300px的Container'),
		  Wrap(
			  children: [
		      ...List.generate(
		          5,
		          (_) => const Text('123456456'),
		          )
		        ],
		      )
		    ],
		  ),
	decoration: BoxDecoration(color: Colors.black26),
),
    

https://ithelp.ithome.com.tw/upload/images/20210930/20112906e5norVmztW.png


我个人是觉得会使用 ContainerRowColumn 就能完成一些很基础的排版需求了,剩下的等实际开发时遇到再来说明。

明天就来做我们第一个小专案也顺便开始真正的运用状态管理。


免费美国电话号码 Google Voice 0月租

免费美国电话号码 Google Voice 0月租

使用Google Voice服务可以免费拨打美国或加拿大境内的任何电话,而国际电话(非北美地区)的费用也比传统电话便宜,比如拨打中国大陆的价格为1美分/分钟,香港的价格为2美分/分钟,台湾市话:2美...

国内注册公司和国外注册公司区别:注册国外公司好还是用国内公司好?

国内注册公司和国外注册公司区别:注册国外公司好还是用国内公司好?

国内公司、香港公司、美国公司是目前绝大部分跨境卖家的身份选择。国内公司身份自然不必多说,90%+都是。香港和美国公司则少的多。但选择的人多并不表示国内公司就是最佳的经营跨境电商身份选择。 国内公司 首...

网站打开速度慢怎么办?为什么网站一定要打开快

在深入探讨提高网站速度之前,让我们探讨一下为什么它对您的小型企业如此重要。 更快的网站意味着: 更好的用户体验 您的网站性能会影响用户的体验 - 当您的网站加载速度更快时,用户更有可能与之互动并花费更...

如何提高网站访问速度:怎么让网站更快打开的方法

网站速度优化对于创造积极的用户体验至关重要。 积极的用户体验是快乐用户的营销代言词。 快乐的用户访问您的网站并购买东西。 不满意的用户离开是因为他们厌倦了等待您的网站加载。 营销人员称之为“跳出率”...

网站服务器怎么选?如何选择最好的网站服务器

为什么网站速度很重要 到目前为止,您应该不需要说服网站速度对您的在线业务至关重要。 这是因为网站性能会影响您的品牌声誉、SEO 排名和转化率。 以下是发生这种情况的主要原因: 品牌口碑👍 老实说,当...

返回顶部