直接開始幹,沒有為什麼~
在Flutter開始干係列-官方入門計數Demo的最後,簡單介紹了 Demo 所使用到的 Widget 。今天實現個登陸頁,介紹一些 FLutter 常用到的 Widget,可以說麻雀雖小部件不少。實際效果如下:
專案地址放在文後,看完效果圖先羅列使用到以及今天要介紹的 Widget,StatelessWidget、StatefulWidget、MaterialApp、Scaffold、AppBar、SingleChildScrollView、Container、Padding、Column、Image、Text、TextField、RaisedButton,可以把專案跑起來對照下文看,接下來對他們的一些常用或可能用到的一些屬性做一個註解。
應用與頁面
StatelessWidget
頁面一旦生成後,資料狀態就不可改變,請使用用 StatelessWidget
StatefulWidget
頁面生成後,資料狀態就可改變,請使用用 StatefulWidget
MaterialApp
MaterialApp 代表一個使用 Material 風格的應用
const MaterialApp({
Key key,
this.navigatorKey,
this.home, // 進入應用的預設介面
this.routes = const <String, WidgetBuilder>{}, // 應用路由導航陣列
this.initialRoute, // 預設初始化的路由
this.onGenerateRoute, // 生成路由時回撥
this.onUnknownRoute,
this.navigatorObservers = const <NavigatorObserver>[],
this.builder,
this.title = '', // 多工視窗顯示的應用名稱
this.onGenerateTitle,
this.color,
this.theme, // 應用 UI 使用的主題風格
this.darkTheme,
this.themeMode = ThemeMode.system,
this.locale, // 帶 locale ,均與多語言設定相關
this.localizationsDelegates,
this.localeListResolutionCallback,
this.localeResolutionCallback,
this.supportedLocales = const <Locale>[Locale('en', 'US')], // 預設支援的語言環境,所以部分系統部件,預設不會顯示中文
this.debugShowMaterialGrid = false,
this.showPerformanceOverlay = false,
this.checkerboardRasterCacheImages = false,
this.checkerboardOffscreenLayers = false,
this.showSemanticsDebugger = false,
this.debugShowCheckedModeBanner = true, // 是否顯示 DEBUG 標識
})
複製程式碼
MaterialApp 主要用於應用整體配置,包含應用主題、路由、多語言以及一些除錯開關。從它的預設引數也可看出一個問題,就是預設支援英語語言環境,所以 TextField 長按操作選單,預設情況僅顯示英文。
解決方案:看專案關於語言設定部分。
Scaffold
Scaffold 用來來快速構建一個 Material Design 風格的頁面,原本需要我們自己做的事情,系統幫我們做了。
Scaffold({
Key key,
this.appBar, // 顯示在頂部的一個部件 AppBar(個人叫做標題欄)
this.body, // 頁面主體內容 Widget
this.floatingActionButton, // Material 中定義的懸浮按鈕
this.floatingActionButtonLocation, // 控制懸浮按鈕位置
this.floatingActionButtonAnimator, // 懸浮按鈕動畫
this.persistentFooterButtons, // 固定顯示在頁面下方的按鈕,在body和bottomNavigationBar之間
this.drawer, // 頁面左側側邊欄
this.endDrawer, // 頁面右側側邊欄
this.bottomNavigationBar, // 頁面底部導航欄
this.bottomSheet, // 顯示在頁面底部的疊加層
this.backgroundColor, // 頁面背景顏色
this.resizeToAvoidBottomPadding, // 頁面內容是否重新佈局 已過時
this.resizeToAvoidBottomInset, // 頁面內容是否重新佈局 推薦使用
this.primary = true, // 是否需要顯示到螢幕頂部(白話:狀態列是否有個 padding)
this.drawerDragStartBehavior = DragStartBehavior.start,
this.extendBody = false, //是否擴充套件body,當頁面有 bottomNavigationBar 或 persistentFooterButtons時,body 擴充套件到他們下面,即被他們覆蓋
this.drawerScrimColor, //側邊欄
this.drawerEdgeDragWidth,
}
複製程式碼
Scaffold 主要用於應用頁面配置,相當於系統給我們搭建了個頁面框架,在這裡我們可以快速的實現標題欄,內容,底部導航欄以及側邊欄等等,當然有一些屬性我們還是很少用到,知道並使用預設就好。
Widget 部件
AppBar
AppBar 頁面頂部導航欄,應用欄,但是我習慣了叫標題欄
AppBar({
Key key,
this.leading, // leading 顯示在[標題]之前的部件,比如抽屜選單、返回按鈕
this.automaticallyImplyLeading = true, // 是否自動實現 leading
this.title, // 顯示標題
this.actions, // 右側
this.flexibleSpace, // 堆疊在標題欄後面部件,高度與標題欄高度相同。
this.bottom, // 標題欄底部選單,通常為Tab按鈕組
this.elevation, // 標題欄陰影
this.shape,
this.backgroundColor, //標題欄背景色
this.brightness, // 標題欄亮度,設定為 light 狀態列文字則為黑色
this.iconTheme, // 以下4個各種樣式
this.actionsIconTheme,
this.textTheme,
this.primary = true,
this.centerTitle, // 是否居中頁面標題
this.titleSpacing = NavigationToolbar.kMiddleSpacing,
this.toolbarOpacity = 1.0, //透明度
this.bottomOpacity = 1.0,
})
複製程式碼
SingleChildScrollView
只有一個子 widger 的 ScrollView,當介面內容超過螢幕的時候( 當你在螢幕上看到類似 bottom overflowed by 216 pixels),包裹一個 SingleChildScrollView 是個很好的解決方式。SingleChildScrollView 適用於內容不會超過螢幕太多時,如果超出太多建議適用 ListView 支援複用。
SingleChildScrollView({
Key key,
this.scrollDirection = Axis.vertical, // 滾動放下
this.reverse = false, // 是否反向滾動
this.padding, // 內邊距
bool primary,
this.physics, // 如何響應使用者輸入
this.controller,
this.child,
this.dragStartBehavior = DragStartBehavior.start,
})
複製程式碼
Container
Container 可以看成一個容器,方便我們指定寬高、內外邊距、背景色等等等
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,
})
複製程式碼
Padding
這就沒啥了,就是一個 Padding 內邊距
Padding({
Key key,
@required this.padding,
Widget child,
})
複製程式碼
Column
Column 豎向線性佈局,預設將一組 Widget 從上至下襬放,需要注意主軸方向(Widget 擺放方向)和從軸方向(與擺放方向垂直)
Column({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, // 主軸對齊方式
MainAxisSize mainAxisSize = MainAxisSize.max, // 主軸每個Item行高
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, // 從軸對齊方式
TextDirection textDirection, // 子元件的佈局順序時 從左至右還是從右至左
VerticalDirection verticalDirection = VerticalDirection.down, // 主軸佈局方向
TextBaseline textBaseline, // 水平對齊基線
List<Widget> children = const <Widget>[],
})
複製程式碼
Image
Flutter 中的圖片顯示部件,可以載入網路、檔案、記憶體以及asset中圖片資源,一般使用 Image.asset、Image.network、Image.file、Image.memory 進行載入
Image({
Key key,
@required this.image, // ImageProvider
this.frameBuilder,
this.loadingBuilder,
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, //圖片過濾質量
})
複製程式碼
Text、RichText
- Text 普通文字部件
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, // 文字寬度包含方式; parent:以父部件寬度包含,longestLine:以最長行包含
})
複製程式碼
- RichText 富文字部件
RichText({
Key key,
@required this.text, // 這裡是個 InlineSpan 其他屬性都和 Text 差不多
this.textAlign = TextAlign.start,
this.textDirection,
this.softWrap = true,
this.overflow = TextOverflow.clip,
this.textScaleFactor = 1.0,
this.maxLines,
this.locale,
this.strutStyle,
this.textWidthBasis = TextWidthBasis.parent,
})
複製程式碼
本文Demo裡面隱私協議部分即用到了富文字,當然實現富文字部件也可以用 Text.rich 方式。
TextField
Flutter 中文字輸入可以使用 TextField 、 TextFromField
TextField({
Key key,
this.controller, // 文字編輯控制器 可以設定監聽 設定預設值 取值等
this.focusNode, // 輸入框焦點
this.decoration = const InputDecoration(), // 輸入框樣式
TextInputType keyboardType, // 輸入框鍵盤型別
this.textInputAction, // 文字輸入 鍵盤事件
this.textCapitalization = TextCapitalization.none,
this.style, // 輸入文字樣式
this.strutStyle,
this.textAlign = TextAlign.start, // 文字對齊方式
this.textAlignVertical, // 豎向對齊方式
this.textDirection, // 文字方向
this.readOnly = false,
ToolbarOptions toolbarOptions,
this.showCursor, // 是否顯示游標
this.autofocus = false, // 是否自動獲取焦點
this.obscureText = false, // 是否隱藏文字
this.autocorrect = true,
this.maxLines = 1, // 最大行數
this.minLines, // 最小行數
this.expands = false,
this.maxLength, // 最大長度
this.maxLengthEnforced = true, // 是否執行maxLength
this.onChanged, // 內容變化回撥
this.onEditingComplete, // 編輯完成回撥
this.onSubmitted, // 提交回撥
this.inputFormatters, // 輸入格式化
this.enabled, // 是否可輸入
this.cursorWidth = 2.0, // 游標寬度
this.cursorRadius, // 游標圓角
this.cursorColor, // 游標顏色
this.keyboardAppearance, // 鍵盤外觀 iOS裝置有效
this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.start,
this.enableInteractiveSelection = true,
this.onTap, // 點選事件
this.buildCounter,
this.scrollController, // 滾動控制器
this.scrollPhysics,
})
複製程式碼
RaisedButton
在 Flutter 中有很多 Button,比如這裡的浮動按鈕 RaisedButton 和與之對應扁平按鈕 FlatButton,還有IconButton、OutlineButton 等,這裡說明下浮動按鈕屬性。
RaisedButton({
Key key,
@required VoidCallback onPressed, // 按下回撥
ValueChanged<bool> onHighlightChanged,
ButtonTextTheme textTheme, // 按鈕文字主題
Color textColor, // 文字顏色
Color disabledTextColor, // 禁用時文字顏色
Color color, // 背景色
Color disabledColor, // 禁用時背景色
Color focusColor,
Color hoverColor,
Color highlightColor, // 按下時背景色
Color splashColor, // 點選時水波紋顏色
Brightness colorBrightness, // 顏色亮度
double elevation, // 陰影
double focusElevation,
double hoverElevation,
double highlightElevation, // 按下時陰影
double disabledElevation, // 禁用時陰影
EdgeInsetsGeometry padding, // 內邊距
ShapeBorder shape, // 邊框外形
Clip clipBehavior,
FocusNode focusNode,
bool autofocus = false, // 是否自動獲取焦點
MaterialTapTargetSize materialTapTargetSize,
Duration animationDuration,
Widget child,
})
複製程式碼
介紹了登陸頁面用到的 Widget 很多屬性,但實際我們可能用不了這麼多,瞭解它的最好的辦法就是寫個Demo,各個屬性都設定取消試試。