一個widget,它沿著一個給定的軸,順序排列它的子元素
創(chuàng)新互聯專注于企業(yè)成都營銷網站建設、網站重做改版、蠡縣網站定制設計、自適應品牌網站建設、H5建站、購物商城網站建設、集團公司官網建設、外貿營銷網站建設、高端網站制作、響應式網頁設計等建站業(yè)務,價格優(yōu)惠性價比高,為蠡縣等各大城市提供網站開發(fā)制作服務。
注意點:
最后這幾個組件怎么使用看需求選擇最適合的就行。
Flutter(5):基礎組件之Row/Column
Flutter(33):Material組件之ListTile、RefreshIndicator、ListView、Divider
下一節(jié):Layout組件之CustomMultiChildLayout
Row:在水平方向上排列子widget的列表。
Column:在垂直方向上排列子widget的列表。
注意:這兩個屬于多子節(jié)點空間,可以將children排列成一行/一列,但是自身不帶滾動屬性,如果超出了一行,在debug下面則會顯示溢出的提示。
MainAxisAlignment:主軸方向上的對齊方式,會對child的位置起作用,默認是start。
其中MainAxisAlignment枚舉值:
center:將children放置在主軸的中心;
end:將children放置在主軸的末尾;
spaceAround:將主軸方向上的空白區(qū)域均分,使得children之間的空白區(qū)域相等,但是首尾child的空白區(qū)域為1/2;
spaceBetween:將主軸方向上的空白區(qū)域均分,使得children之間的空白區(qū)域相等,首尾child都靠近首尾,沒有間隙;
spaceEvenly:將主軸方向上的空白區(qū)域均分,使得children之間的空白區(qū)域相等,包括首尾child;
start:將children放置在主軸的起點;
其中spaceAround、spaceBetween以及spaceEvenly的區(qū)別,就是對待首尾child的方式。其距離首尾的距離分別是空白區(qū)域的1/2、0、1。
MainAxisSize:在主軸方向占有空間的值,默認是max。
MainAxisSize的取值有兩種:
max:根據傳入的布局約束條件,最大化主軸方向的可用空間;
min:與max相反,是最小化主軸方向的可用空間;
CrossAxisAlignment:children在交叉軸方向的對齊方式,與MainAxisAlignment略有不同。
CrossAxisAlignment枚舉值有如下幾種:
baseline:在交叉軸方向,使得children的baseline對齊;
center:children在交叉軸上居中展示;
end:children在交叉軸上末尾展示;
start:children在交叉軸上起點處展示;
stretch:讓children填滿交叉軸方向;
TextDirection:阿拉伯語系的兼容設置,一般無需處理。
VerticalDirection:定義了children擺放順序,默認是down。
VerticalDirection枚舉值有兩種:
down:從top到bottom進行布局;
up:從bottom到top進行布局。
top對應Row以及Column的話,就是左邊和頂部,bottom的話,則是右邊和底部。
TextBaseline:使用的TextBaseline的方式,有兩種,前面已經介紹過。
這個是Row/Column的內的小控件,可以用來實現權重的布局
這邊使用一個Container,里面是Row,使用Expanded對子節(jié)點進行權重處理,如果不使用Expanded,直接放入其他控件也是可以的,只是無法設置權重
對于內容過長的時候,會有溢出提示:
MainAxisAlignment.center:將children放置在主軸的中心;
MainAxisAlignment.start:將children放置在主軸的起點;
MainAxisAlignment.end:將children放置在主軸的末尾;
MainAxisAlignment.spaceAround:將主軸方向上的空白區(qū)域均分,使得children之間的空白區(qū)域相等,但是首尾child的空白區(qū)域為1/2;
MainAxisAlignment.spaceBetween:將主軸方向上的空白區(qū)域均分,使得children之間的空白區(qū)域相等,首尾child都靠近首尾,沒有間隙;
MainAxisAlignment.spaceEvenly:將主軸方向上的空白區(qū)域均分,使得children之間的空白區(qū)域相等,包括首尾child;
下一章我們學習基礎組件之Image
新建一個Flutter工程,android模塊。
1,只有一個Activity組件,它是Dart層繪制Widget的容器。
2,Application配置FlutterApplication。
應用Application配置io.flutter.app.FlutterApplication類,App首次啟動時,初始化。
調用FlutterMain.startInitialization()方法。
initConfig方法,從AndroidManfest.xml配置的applicaion節(jié)點獲取meta-data數據,初始化以下默認值。
這些值都是使用中用到的name,例如,抽取apk中asset資源時,flutter_assets打包目錄,打包產物data名稱。
initResources方法, 初始化資源。
在Flutter打包apk的asset目錄下,包括fluttter_asset目錄/資源項,將資源從apk中抽取,保存在 Context.getDir("flutter", 0) 目錄下。
/data/user/0/包名/app_flutter目錄。
在目錄中創(chuàng)建一個時間戳文件,根據apk版本和包信息記錄的lastUpdateTime更新時間,第二次啟動時,若apk未更新,不需要再次抽取。
加載so庫,libflutter.so,System.loadLibrary()。
主頁面繼承FlutterActivity,配置啟動模式singleTop。
FlutterActivity類在io.flutter.app包, (區(qū)別io.flutter.embedding.android包), 組件生命周期委托給FlutterActivityDelegate類。
組件啟動,onCreate方法。
FlutterMain.ensureInitializationComplete方法,確保資源成功抽取完成,創(chuàng)建FlutterView視圖(io.flutter.view),繼承SurfaceView類,setContentView方法,設置組件主布局即FlutterView視圖。
最后,根據Bundle路徑,runBundle()加載運行,
調用FlutterView的runFromBundle方法,入口點在dart的main方法,
通過FlutterNativeView,調用FlutterJNI的native方法。
nativeRunBundleAndSnapshotFromLibrary方法。
任重而道遠
Flutter中有兩個常用的狀態(tài)Widget分為StatefulWidget和StatelessWidget,分別為動態(tài)視圖和靜態(tài)視圖,視圖的更新需要調用StatefulWidget的setState方法,這會遍歷調用子Widget的build方法。如果一個頁面內容比較復雜時,會包含多個widget,如果直接調用setState,會遍歷所有子Widget的build,這樣會造成很多不必要的開銷,所以非常有必要了解Flutter中局部刷新的方式:
globalkey唯一定義了某個element,它使你能夠訪問與element相關聯的其他對象,例如buildContext、state等。應用場景:跨widget訪問狀態(tài)。
例如:可以通過key.currentState拿到它的狀態(tài)對象,然后就可以調用其中的onPressed方法。
Flutter框架內部提供了一個非常小巧精致的組件,專門用于局部組件的刷新。適用于值改動的刷新。
實現原理:在 initState 中對傳入的可監(jiān)聽對象進行監(jiān)聽,執(zhí)行 _valueChanged 方法,_valueChanged 中進行了 setState 來觸發(fā)當前狀態(tài)的刷新。觸發(fā) build 方法,從而觸發(fā) widget.builder 回調,這樣就實現了局部刷新??梢钥吹竭@里回調的 child 是組件傳入的 child,所以直接使用,這就是對 child 的優(yōu)化的根源。
可以看到 ValueListenableBuilder 實現局部刷新的本質,也是進行組件的抽離,讓組件狀態(tài)的改變框定在狀態(tài)內部,并通過 builder 回調控制局部刷新,暴露給用戶使用。
通過這個可以創(chuàng)建一個支持局部刷新的widget樹,比如你可以在StatelessWidget里面刷新某個布局,但是不需要改變成StatefulWidget;也可以在StatefulWidget中使用做部分刷新而不需要刷新整個頁面,這個刷新是不會調用Widget build(BuildContext context)刷新整個布局樹的。
異步UI更新:
很多時候我們會依賴一些異步數據來動態(tài)更新UI,比如在打開一個頁面時我們需要先從互聯網上獲取數據,在獲取數據的過程中顯示一個加載框,等獲取到數據時我們再渲染頁面;又比如我們想展示Stream(比如文件流、互聯網數據接收流)的進度。當然StatefulWidget我們完全可以實現以上功能。但由于在實際開發(fā)中依賴異步數據更新UI的這種場景非常常見,并且當StatefulWidget中控件樹較大時,更新一個屬性導致整個樹重建,消耗性能,因此Flutter專門提供了FutureBuilder和SteamBuilder兩個組件來快速實現這種功能。
通常情況下,子Widget無法單獨感知父Widget的變化,當父state變化時,通過其build重建所有子widget;
InheriteddWidget可以避免這種全局創(chuàng)建,實現局部子Widget更新。InheritedWidget提供了一種在Widget樹中從上到下傳遞、共享數據的方式。Flutter SDK正是通過InheritedWidget來共享應用主題和Locale等信息。
InheritedWidgetData
TestData
InheritedTest1Page
provider是Google I/O 2019大會上宣布的現在官方推薦的管理方式,而ChangeNotifierProvider可以說是Provider的一種:
yaml文件需要引入provider: ^3.1.0
頂層嵌套ChangeNotifierProvider
創(chuàng)建共享數據類DataInfo:
數據類需要with ChangeNotifier 以使用 notifyListeners()函數通知監(jiān)聽者更新界面。
使用Provider.of(context)獲取DataInfo
nextPage:
使用Consumer包住需要使用共享數據的Widget
RepaintBoundary就是重繪邊界,用于重繪時獨立于父視圖。頁面需要更新的頁面結構可以用 RepaintBoundary組件嵌套,flutter 會將包含的組件獨立出一層"畫布",去繪制。官方很多組件 外層也包了層 RepaintBoundary 標簽。如果你的自定義view比較復雜,應該盡可能的避免重繪。
以上總結了幾種Flutter的局部刷新的方式,可根據實際需要使用不同的方式,最適合的才是最好的。
Text繼承自 StatelessWidget ,Text 主要通過設置 文本布局 及 文本樣式 控制顯示方式。
1. 文本布局: 例如文本對齊方式 textAlign 、文本排版方向 textDirection ,文本顯示最大行數 maxLines 、文本截斷規(guī)則 overflow 等等
2 文本樣式: 如字體名稱 fontFamily 、字體大小 fontSize 、文本顏色 color 、文本陰影 shadows 等等,這些參數被統(tǒng)一封裝到了構造函數中的參數 style(TextStyle) 中
??在iOS中,我們可以使用NSAttributedString進行富文本設置。在Flutter中 我們可以通過 Text.rich() 或 RichText() 進行富文本設置。
兩者均為 InlineSpan 類型, InlineSpan 為抽象類。
抽象類不能直接實例化。Flutter已為我們提供了
且 WidgetSpan 繼承自 PlaceholderSpan
Image是一個用于展示圖片的組件。支持 JPEG、PNG、GIF、Animated GIF、WebP、Animated WebP、BMP 和 WBMP 等格式。
Image.asset - 用于從資源目錄的顯示圖片,需要在 pubspec.yaml 文件中聲明。
Image.network - 用于從網絡上顯示圖片。
Image.file - 用于從文件里顯示圖片。
Image.memory - 用于從內存里(Uint8List)顯示圖片。
alignment → AlignmentGeometry - 圖像邊界內對齊圖像。
centerSlice → Rect - 九片圖像的中心切片。
color → Color - 該顏色與每個圖像像素混合colorBlendMode。
colorBlendMode → BlendMode - 用于 color 與此圖像結合使用。
fit → BoxFit - 圖像在布局中分配的空間。
gaplessPlayback → bool - 當圖像提供者發(fā)生變化時,是繼續(xù)顯示舊圖像(true)還是暫時不顯示(false)。
image → ImageProvider - 要顯示的圖像。
matchTextDirection → bool - 是否在圖像的方向上繪制圖像 TextDirection。
repeat → ImageRepeat - 未充分容器時,是否重復圖片。
height → double - 圖像的高度。
width → double - 圖像的寬度。
加載資源圖片需要將圖片資源放入工程中,例如:新建images文件夾,將圖片放在該文件夾下,圖片適配則是使用ios的方式1X,2X,3X:
然后在pubspec.yaml中配置assets:
加載資源/網絡/本地文件圖片/內存圖片:
占位圖加載圖片:
圓形圖片:1.裁剪實現 2.CircleAvatar實現 3.Container邊框實現
圓角圖片:1.裁剪實現 2.Container邊框實現
BoxFit.contain 全圖居中顯示但不充滿,顯示原比例
BoxFit.cover 圖片可能拉伸,也可能裁剪,但是充滿容器
BoxFit.fill 全圖顯示且填充滿,圖片可能會拉伸
BoxFit.fitHeight 圖片可能拉伸,可能裁剪,高度充滿
BoxFit.fitWidth 圖片可能拉伸,可能裁剪,寬度充滿
BoxFit.scaleDown 效果和contain差不多, 但是只能縮小圖片,不能放大圖片
下一節(jié)學習基礎組件之Text