Flutter布局入門
一、Widget簡介
描述
Fullter的核心思想是用widget 來構(gòu)建你的 UI 界面晌坤。 Widget 描述了在當(dāng)前的配置和狀態(tài)下視圖所應(yīng)該呈現(xiàn)的樣子杈湾。當(dāng) widget 的狀態(tài)改變時(shí)耸采,它會(huì)重新構(gòu)建其描述(展示的 UI)队丝,框架則會(huì)對(duì)比前后變化的不同忠怖,以確定底層渲染樹從一個(gè)狀態(tài)轉(zhuǎn)換到下一個(gè)狀態(tài)所需的最小更改港准。
以上是Widget官方解釋旨剥,所以Widget和我們通常所說的View不一樣,widget不是一個(gè)控件浅缸,它是對(duì)控件的描述(我們?cè)谌腴T時(shí)并不需要太過糾結(jié)Widget是什么轨帜,只需知道它是構(gòu)建UI即可)。
下面我們官方demo衩椒,神圣的“Hello World”
import 'package:flutter/material.dart';
void main() {
runApp(
Center(
child: Text(
'Hello, world!',
textDirection: TextDirection.ltr,
),
),
);
}
這個(gè)demo官方文檔有相關(guān)解釋有興趣的可以查看蚌父,就不具體贅述了,具體的Center Text會(huì)在后面詳解毛萌。
1.2苟弛、Widget分類
Widget的種類有很多,官方做了如下分類
- Accessibility
- Animation and Motion 給你的應(yīng)用程序添加動(dòng)畫阁将。
- Assets, Images, and Icons
- Async Flutter應(yīng)用程序的異步Widget膏秫。
- Basics 在構(gòu)建第一個(gè)Flutter應(yīng)用程序之前,需要知道的Basics Widget做盅。
- Cupertino (iOS-style widgets) iOS風(fēng)格的Widget荔睹。
- Input 除了在Material Components和Cupertino中的輸入Widget外狸演,還可以接受用戶輸入的Widget。
- Interaction Models 響應(yīng)觸摸事件并將用戶路由到不同的視圖中僻他。
- Layout 用于布局的Widget宵距。
- Material Components Material Design風(fēng)格的Widget。
- Painting and effects 不改變布局吨拗、大小满哪、位置的情況下為子Widget應(yīng)用視覺效果。
- Scrolling 滾動(dòng)相關(guān)的Widget劝篷。
- Styling 主題哨鸭、填充相關(guān)Widget。
- Text 顯示文本和文本樣式娇妓。
Widget詳解
Widget類
在Widget的構(gòu)造方法中有一個(gè)參數(shù)key
/// Initializes [key] for subclasses.
const Widget({ this.key });
這個(gè)key的作用是用來控制在widget樹中替換widget的時(shí)候使用的像鸡,key作為唯一標(biāo)識(shí)。
State
我們常用的Widget有兩種哈恰,StatelessWidget只估、StatefulWidget,在了解State之前着绷,看下二者之間的區(qū)別蛔钙,其實(shí)可以根據(jù)字面意思大致猜到
- StatelessWidget:無中間狀態(tài)變化的 widget,需要更新展示內(nèi)容的話,就得通過重新 new荠医。
- StatefulWidget:具有可變狀態(tài)(State)的Widget吁脱,在狀態(tài)改變是調(diào)用State.setState()通知狀態(tài)改變,刷新狀態(tài)
State生命周期
State生命周期可以分為三個(gè)階段:
- 初始化:
- 狀態(tài)改變:
-
銷毀:
完整的生命周期
initState:widget創(chuàng)建執(zhí)行的第一個(gè)方法彬向,可以再里面初始化一些數(shù)據(jù)兼贡,以及綁定控制器
didChangeDependencies :當(dāng)State對(duì)象的依賴發(fā)生變化時(shí)會(huì)被調(diào)用;例如:在之前build()中包含了一個(gè)InheritedWidget娃胆,然后在之后的build() 中InheritedWidget發(fā)生了變化紧显,那么此時(shí)InheritedWidget的子widget的didChangeDependencies()回調(diào)都會(huì)被調(diào)用。InheritedWidget這個(gè)widget可以由父控件向子控件共享數(shù)據(jù)缕棵。
reassemble:此回調(diào)是專門為了開發(fā)調(diào)試而提供的,在熱重載(hot reload)時(shí)會(huì)被調(diào)用涉兽,此回調(diào)在Release模式下永遠(yuǎn)不會(huì)被調(diào)用招驴。
didUpdateWidget:當(dāng)樹rebuid的時(shí)候會(huì)調(diào)用該方法。
deactivate:當(dāng)State對(duì)象從樹中被移除時(shí)枷畏,會(huì)調(diào)用此回調(diào)别厘。
dispose():當(dāng)State對(duì)象從樹中被永久移除時(shí)調(diào)用;通常在此回調(diào)中釋放資源拥诡。
StatelessWidget
class MyStatelessWidget extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Container(color: const Color(0xFF2DBD3A));
}
}
StatelessWidget的build方法通常會(huì)在以下三種情況被調(diào)用:
- 將widget插入樹中時(shí)
- 當(dāng)widget的父級(jí)更改其配置時(shí)
- 當(dāng)它依賴的InheritedWidget發(fā)生變化時(shí)
StatefulWidget
StatefulWidget是有可變狀態(tài)的Widget触趴。
- 在initState中創(chuàng)建資源氮发,在dispose中銷毀,但是不依賴于InheritedWidget或者調(diào)用setState方法冗懦,這類widget基本上用在一個(gè)應(yīng)用或者頁面的root爽冕;
- 使用setState或者依賴于InheritedWidget,這種在營業(yè)生命周期中會(huì)被重建(rebuild)很多次披蕉。
class MyHomePage extends StatefulWidget {
const YellowBird({ Key key }) : super(key: key);
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<YellowBird> {
@override
Widget build(BuildContext context) {
return new Container(color: const Color(0xFFFFE306));
}
}
二 基本組件
Container
Container在Flutter很常見颈畸。官方給出的簡介,是一個(gè)結(jié)合了繪制(painting)没讲、定位(positioning)以及尺寸(sizing)widget的widget眯娱。
組成
Container的組成如下:
- 最里層的是child元素;
- child元素首先會(huì)被padding包著爬凑;
- 然后添加額外的constraints限制徙缴;
- 最后添加margin。
Container的繪制的過程如下:
- 首先會(huì)繪制transform效果嘁信;
- 接著繪制decoration于样;
- 然后繪制child;
- 最后繪制foregroundDecoration吱抚。
Container自身尺寸的調(diào)節(jié)分兩種情況:
- Container在沒有子節(jié)點(diǎn)(children)的時(shí)候百宇,會(huì)試圖去變得足夠大。除非constraints是unbounded限制秘豹,在這種情況下携御,Container會(huì)試圖去變得足夠小。
- 帶子節(jié)點(diǎn)的Container既绕,會(huì)根據(jù)子節(jié)點(diǎn)尺寸調(diào)節(jié)自身尺寸啄刹,但是Container構(gòu)造器中如果包含了width、height以及constraints凄贩,則會(huì)按照構(gòu)造器中的參數(shù)來進(jìn)行尺寸的調(diào)節(jié)誓军。
布局行為
由于Container組合了一系列的widget,這些widget都有自己的布局行為疲扎,因此Container的布局行為有時(shí)候是比較復(fù)雜的昵时。
一般情況下,Container會(huì)遵循如下順序去嘗試布局:
- 對(duì)齊(alignment)椒丧;
- 調(diào)節(jié)自身尺寸適合子節(jié)點(diǎn)壹甥;
- 采用width、height以及constraints布局壶熏;
- 擴(kuò)展自身去適應(yīng)父節(jié)點(diǎn)句柠;
- 調(diào)節(jié)自身到足夠小。
進(jìn)一步說:
- 如果沒有子節(jié)點(diǎn)、沒有設(shè)置width溯职、height以及constraints精盅,并且父節(jié)點(diǎn)沒有設(shè)置unbounded的限制,Container會(huì)將自身調(diào)整到足夠小谜酒。
- 如果沒有子節(jié)點(diǎn)叹俏、對(duì)齊方式(alignment),但是提供了width甚带、height或者constraints她肯,那么Container會(huì)根據(jù)自身以及父節(jié)點(diǎn)的限制,將自身調(diào)節(jié)到足夠小鹰贵。
- 如果沒有子節(jié)點(diǎn)晴氨、width、height碉输、constraints以及alignment籽前,但是父節(jié)點(diǎn)提供了bounded限制,那么Container會(huì)按照父節(jié)點(diǎn)的限制敷钾,將自身調(diào)整到足夠大枝哄。
- 如果有alignment,父節(jié)點(diǎn)提供了unbounded限制阻荒,那么Container將會(huì)調(diào)節(jié)自身尺寸來包住child挠锥;
- 如果有alignment,并且父節(jié)點(diǎn)提供了bounded限制侨赡,那么Container會(huì)將自身調(diào)整的足夠大(在父節(jié)點(diǎn)的范圍內(nèi))蓖租,然后將child根據(jù)alignment調(diào)整位置;
- 含有child羊壹,但是沒有width蓖宦、height、constraints以及alignment油猫,Container會(huì)將父節(jié)點(diǎn)的constraints傳遞給child稠茂,并且根據(jù)child調(diào)整自身。
另外情妖,margin以及padding屬性也會(huì)影響到布局睬关。
構(gòu)造方法
Container({
Key key,
this.alignment,
this.padding,
Color color,
Decoration decoration,
this.foregroundDecoration,
double width,
double height,
BoxConstraints constraints,
this.margin,
this.transform,
this.child,
})
平時(shí)使用最多的,也就是padding毡证、color电爹、width、height情竹、margin屬性。
屬性解析
alignment:控制child的對(duì)齊方式,如果container或者container父節(jié)點(diǎn)尺寸大于child的尺寸秦效,這個(gè)屬性設(shè)置會(huì)起作用雏蛮,有很多種對(duì)齊方式。
padding:decoration內(nèi)部的空白區(qū)域阱州,如果有child的話挑秉,child位于padding內(nèi)部。padding與margin的不同之處在于苔货,padding是包含在content內(nèi)犀概,而margin則是外部邊界,設(shè)置點(diǎn)擊事件的話夜惭,padding區(qū)域會(huì)響應(yīng)姻灶,而margin區(qū)域不會(huì)響應(yīng)。
color:用來設(shè)置container背景色诈茧,如果foregroundDecoration設(shè)置的話产喉,可能會(huì)遮蓋color效果。
decoration:繪制在child后面的裝飾敢会,設(shè)置了decoration的話曾沈,就不能設(shè)置color屬性,否則會(huì)報(bào)錯(cuò)鸥昏,此時(shí)應(yīng)該在decoration中進(jìn)行顏色的設(shè)置塞俱。
foregroundDecoration:繪制在child前面的裝飾。
width:container的寬度吏垮,設(shè)置為double.infinity可以強(qiáng)制在寬度上撐滿障涯,不設(shè)置,則根據(jù)child和父節(jié)點(diǎn)兩者一起布局惫皱。
height:container的高度像樊,設(shè)置為double.infinity可以強(qiáng)制在高度上撐滿。
constraints:添加到child上額外的約束條件旅敷。
margin:圍繞在decoration和child之外的空白區(qū)域生棍,不屬于內(nèi)容區(qū)域。
transform:設(shè)置container的變換矩陣媳谁,類型為Matrix4涂滴。
child:container中的內(nèi)容widget。
代碼示例
new Container(
constraints: new BoxConstraints.expand(
height:Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0,
),
decoration: new BoxDecoration(
border: new Border.all(width: 2.0, color: Colors.red),
color: Colors.grey,
borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
image: new DecorationImage(
image: new NetworkImage('https://hosjoy-iot.oss-cn-hangzhou.aliyuncs.com/images/public/LKM.png'),
centerSlice: new Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0),
),
),
padding: const EdgeInsets.all(8.0),
alignment: Alignment.center,
child: new Text('Hello World',
style: Theme.of(context).textTheme.display1.copyWith(color: Colors.black)),
transform: new Matrix4.rotationZ(0.3),
)
其中decoration可以設(shè)置邊框晴音、背景色柔纵、背景圖片、圓角等屬性锤躁。對(duì)于transform這個(gè)屬性搁料,一般不是變換的實(shí)際位置,而是變換的繪制效果,也就是說它的點(diǎn)擊以及尺寸郭计、間距等都是按照未變換前的霸琴。
Row、Column
Row
Row({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
MainAxisSize mainAxisSize = MainAxisSize.max,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
TextDirection textDirection,
VerticalDirection verticalDirection = VerticalDirection.down,
TextBaseline textBaseline,
List<Widget> children = const <Widget>[],
})
header 1 | header 2 |
---|---|
MainAxisAlignment | 主軸方向上的對(duì)齊方式昭伸,會(huì)對(duì)child的位置起作用梧乘,默認(rèn)是start。 |
MainAxisSize | 在主軸方向占有空間的值庐杨,默認(rèn)是max选调。 |
CrossAxisAlignment | children在交叉軸方向的對(duì)齊方式,與MainAxisAlignment略有不同 |
VerticalDirection | children擺放順序灵份,默認(rèn)是down仁堪。 |
TextBaseline | 使用的TextBaseline的方式 |
MainAxisAlignment值:
- center:將children放置在主軸的中心;
- end:將children放置在主軸的末尾各吨;
- spaceAround:將主軸方向上的空白區(qū)域均分枝笨,使得children之間的空白區(qū)域相等,但是首尾child的空白區(qū)域?yàn)?/2揭蜒;
- spaceBetween:將主軸方向上的空白區(qū)域均分横浑,使得children之間的空白區(qū)域相等,首尾child都靠近首尾屉更,沒有間隙徙融;
- spaceEvenly:將主軸方向上的空白區(qū)域均分,使得children之間的空白區(qū)域相等瑰谜,包括首尾child欺冀;
- start:將children放置在主軸的起點(diǎn);
MainAxisSize的取值:
- max:根據(jù)傳入的布局約束條件萨脑,最大化主軸方向的可用空間隐轩;
- min:與max相反,是最小化主軸方向的可用空間渤早;
CrossAxisAlignment的值:
- baseline:在交叉軸方向职车,使得children的baseline對(duì)齊;
- center:children在交叉軸上居中展示鹊杖;
- end:children在交叉軸上末尾展示悴灵;
- start:children在交叉軸上起點(diǎn)處展示;
- stretch:讓children填滿交叉軸方向骂蓖;
VerticalDirection的值:
- down:從top到bottom進(jìn)行布局积瞒;
- up:從bottom到top進(jìn)行布局。
Column
Column與Row類似只是排列方式不同登下,不再贅述
文本組件Text
構(gòu)造函數(shù)
const Text(
this.data, {
Key key,
this.style,
this.strutStyle,
this.textAlign,
this.textDirection,
this.locale,
this.softWrap,
this.overflow,
this.textScaleFactor,
this.maxLines,
this.semanticsLabel,
this.textWidthBasis,
})
const Text.rich(
this.textSpan, {
Key key,
this.style,
this.strutStyle,
this.textAlign,
this.textDirection,
this.locale,
this.softWrap,
this.overflow,
this.textScaleFactor,
this.maxLines,
this.semanticsLabel,
this.textWidthBasis,
})
text有兩個(gè)構(gòu)造函數(shù)茫孔,第一個(gè)是默認(rèn)叮喳,第二個(gè)是實(shí)現(xiàn)Text.rich樣式的,和 Android 中的 SpannableString 一樣缰贝,具體API屬性如下:
屬性 | 含義 |
---|---|
textAlign | 文本對(duì)齊方式(center居中嘲更,left左對(duì)齊,right右對(duì)齊揩瞪,justfy兩端對(duì)齊) |
textDirection | 文本方向(ltr從左至右,rtl從右至左) |
softWare | 是否自動(dòng)換行(true自動(dòng)換行篓冲,false單行顯示李破,超出屏幕部分默認(rèn)截?cái)嗵幚恚?/td> |
overflow | 文字超出屏幕之后的處理方式(clip裁剪,fade漸隱壹将,ellipsis省略號(hào)) |
textScaleFactor | 字體顯示倍率 |
maxLines | 文字顯示最大行數(shù) |
style | 字體的樣式設(shè)置 |
代碼示例
child: new Column(
children: <Widget>[
new Text(
"Unit 1 Lesson 3 About animal",
style: new TextStyle(
fontFamily: "Round", fontSize: 20, color: Colors.white),
),
Text('默認(rèn)text'),
Padding(
padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
child: Text(
'Flutter擁有豐富的工具和庫嗤攻,可以幫助您輕松地同時(shí)在iOS和Android系統(tǒng)中實(shí)現(xiàn)您的想法和創(chuàng)意。',
//是否自動(dòng)換行 false文字不考慮容器大小诽俯,單行顯示妇菱,超出屏幕部分將默認(rèn)截?cái)嗵幚? softWrap: true,
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
child: Text(
'Flutter擁有豐富的工具和庫,可以幫助您輕松地同時(shí)在iOS和Android系統(tǒng)中實(shí)現(xiàn)您的想法和創(chuàng)意暴区。',
//文字超出屏幕之后的處理方式 TextOverflow.clip剪裁 TextOverflow.fade 漸隱 TextOverflow.ellipsis省略號(hào)
overflow: TextOverflow.ellipsis,
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
child: Text(
'Flutter擁有豐富的工具和庫闯团,可以幫助您輕松地同時(shí)在iOS和Android系統(tǒng)中實(shí)現(xiàn)您的想法和創(chuàng)意,可以幫助您輕松地同時(shí)在iOS和Android系統(tǒng)中實(shí)現(xiàn)您的想法和創(chuàng)意仙粱。',
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
child: Text(
'文本方向 Flutter擁有豐富的工具和庫房交,可以幫助您輕松地同時(shí)在iOS和Android系統(tǒng)中實(shí)現(xiàn)您的想法和創(chuàng)意。',
//TextDirection.ltr從左至右伐割,TextDirection.rtl從右至左
textDirection: TextDirection.rtl,
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
child: Text(
'文本對(duì)齊方式 Flutter擁有豐富的工具和庫候味,可以幫助您輕松地同時(shí)在iOS和Android系統(tǒng)中實(shí)現(xiàn)您的想法和創(chuàng)意。',
//TextAlign.left左對(duì)齊隔心,TextAlign.right右對(duì)齊白群,TextAlign.center居中對(duì)齊,TextAlign.justfy兩端對(duì)齊
textAlign: TextAlign.center,
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
child: Text(
'設(shè)置顏色和大小',
style: TextStyle(
color: const Color(0xfff2c222),
fontSize: 20,
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
child: Text(
'設(shè)置粗細(xì)和斜體',
style: TextStyle(
//字體粗細(xì)硬霍,粗體和正常
fontWeight: FontWeight.bold,
//文字樣式帜慢,斜體和正常
fontStyle: FontStyle.italic,
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
child: Text(
'設(shè)置文字裝飾',
style: TextStyle(
//none無文字裝飾,lineThrough刪除線须尚,overline文字上面顯示線崖堤,underline文字下面顯示線
decoration: TextDecoration.underline,
decorationColor: Colors.blue,
decorationStyle: TextDecorationStyle.wavy
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
child: Text(
'單詞間隙 hello world',
style: TextStyle(
wordSpacing: 10.0,
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
child: Text(
'字母間隙 hello world',
style: TextStyle(
letterSpacing: 10.0,
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
child: GestureDetector(
onTap: () {
print("點(diǎn)擊了按鈕");
},
child: Text(
'設(shè)置文字點(diǎn)擊事件',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic,
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
child: Text.rich(
new TextSpan(
text: 'Text.rich',
style: new TextStyle(
color: Colors.blueAccent,
fontSize: 10,
decoration: TextDecoration.none),
children: <TextSpan>[
new TextSpan(
text: '拼接測試1',
style: new TextStyle(
color: Colors.blue,
fontSize: 14,
decoration: TextDecoration.none)),
new TextSpan(
text: '拼接測試2',
style: new TextStyle(
color: Colors.black,
fontSize: 18,
decoration: TextDecoration.none)),
new TextSpan(
text: '拼接測試3',
style: new TextStyle(
color: Colors.red,
fontSize: 22,
decoration: TextDecoration.none)),
new TextSpan(
text: '拼接測試4',
style: new TextStyle(
color: Colors.grey,
fontSize: 26,
decoration: TextDecoration.none)),
]),
),
)
],
),
圖片組件Image
構(gòu)造方法
Image({
Key key,
@required this.image,
this.semanticLabel,
this.excludeFromSemantics = false,
this.width,
this.height,
this.color,
this.colorBlendMode,
this.fit,
this.alignment = Alignment.center,
this.repeat = ImageRepeat.noRepeat,
this.centerSlice,
this.matchTextDirection = false,
this.gaplessPlayback = false,
this.filterQuality = FilterQuality.low,
})
API | 屬性 |
---|---|
BoxFit.contain | 顯示整張圖片,按照原始比例縮放顯示 |
BoxFit.fill | 顯示整張圖片耐床,拉伸填充全部可顯示區(qū)域 |
BoxFit.cover | 按照原始比例縮放密幔,可能裁剪,填滿可顯示區(qū)域 |
BoxFit.fitHeight | 按照原始比例縮放撩轰,可能裁剪胯甩,高度優(yōu)先填滿 |
BoxFit.fitWidth | 按照原始比例縮放昧廷,可能裁剪寬度優(yōu)先填滿 |
BoxFit.none | 圖片居中顯示,不縮放原圖偎箫,可能被裁剪 |
BoxFit.scaleDown | 顯示整張圖片木柬,只能縮小或者原圖顯示 |
colorBlendMode
圖片顏色混合處理,篇幅有限淹办,有興趣的可以點(diǎn)擊鏈接查看
按鈕類組件(IconButton眉枕、RaisedButton)
構(gòu)造方法
const IconButton({
Key key,
this.iconSize = 24.0,
this.padding = const EdgeInsets.all(8.0),
this.alignment = Alignment.center,
@required this.icon,
this.color,
this.highlightColor,
this.splashColor,
this.disabledColor,
@required this.onPressed,
this.tooltip
}) : assert(iconSize != null),
assert(padding != null),
assert(alignment != null),
assert(icon != null),
super(key: key);
屬性 | 含義 |
---|---|
highlightColor | 按鈕處于按下狀態(tài)時(shí)按鈕的輔助顏色。 |
splashColor | 按鈕處于按下狀態(tài)時(shí)按鈕的主要顏色。 |
disabledColor | 圖標(biāo)組件禁用的顏色,默認(rèn)為主題里的禁用顏色 |
onPressed | 點(diǎn)擊或以其他方式激活按鈕時(shí)調(diào)用的回調(diào)低零。如果將其設(shè)置為null,則將禁用該按鈕姥宝。 |
tooltip | 描述按下按鈕時(shí)將發(fā)生的操作的文本。 |
代碼示例
new IconButton(
padding: EdgeInsets.zero,
iconSize: 60.0,
icon: new Image.asset("assets/images/share_wechat.png"),
onPressed: () {
print("share to wechat");
}),
列表類組件ListView
ListView({
Key key,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap = false,
EdgeInsetsGeometry padding,
this.itemExtent,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
double cacheExtent,
List<Widget> children = const <Widget>[],
int semanticChildCount,
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
})
屬性 | 含義 |
---|---|
reverse | 是否反向滾動(dòng) |
controller | 滾動(dòng)控制器 |
primary | 是否是與父級(jí)PrimaryScrollController關(guān)聯(lián)的主滾動(dòng)視圖恐疲。如果primary為true腊满,controller必須設(shè)置 |
shrinkWrap | 滾動(dòng)方向上的滾動(dòng)視圖的范圍是否應(yīng)由所查看的內(nèi)容決定。 |
itemExtent | 子元素長度 |
physics | 列表滾動(dòng)至邊緣后繼續(xù)拖動(dòng)的物理效果 |
cacheExtent | 預(yù)渲染區(qū)域長度 |
代碼示例
child: new ListView.builder(
padding: new EdgeInsets.all(30.0),
itemExtent: 50.0,
itemBuilder: (BuildContext context, int index) {
return new Text("Hosjoy $index");
},
),
網(wǎng)各類組件GridView
構(gòu)造方法
GridView.count({
Key key,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap = false,
EdgeInsetsGeometry padding,
@required int crossAxisCount,
double mainAxisSpacing = 0.0,
double crossAxisSpacing = 0.0,
double childAspectRatio = 1.0,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
double cacheExtent,
List<Widget> children = const <Widget>[],
int semanticChildCount,
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
})
gridView的屬性可以參考ListView培己,下面列舉GrideView特有的屬性
屬性 | 含義 |
---|---|
mainAxisSpacing | itme的水平距離 |
crossAxisSpacing | item的垂直距離 |
childAspectRatio | item的寬高比 |
crossAxisCount | 每行的item個(gè)數(shù) |
代碼示例
GridView.count(padding: const EdgeInsets.all(20.0),
crossAxisSpacing: 10.0,
crossAxisCount: 3,
children: <Widget>[
const Text('Hosjoy'),
new Image.network('https://hosjoy-iot.oss-cn-hangzhou.aliyuncs.com/images/public/LKM.png',fit: BoxFit.cover),
const Text('Hosjoy'),
const Text('Hosjoy'),
new Image.network('https://hosjoy-iot.oss-cn-hangzhou.aliyuncs.com/images/public/LKM.png',fit: BoxFit.cover),
const Text('Hosjoy'),
const Text('Hosjoy'),
new Image.network('https://hosjoy-iot.oss-cn-hangzhou.aliyuncs.com/images/public/LKM.png',fit: BoxFit.cover),
new Image.network('https://hosjoy-iot.oss-cn-hangzhou.aliyuncs.com/images/public/LKM.png',fit: BoxFit.cover),
],
),