隻不過是一隻腳放到另一隻腳前面。但我一直很驚訝這些原本是本能的事實際做起來有多困難。
Widget
Flutter中幾乎所有的對象都是一個Widget,與原生開發中“控件”不同的是,Flutter中的widget的概念更廣泛,它不僅可以表示UI元素,也可以表示一些功能性的元件如:用于手勢檢測的 GestureDetector widget、用于應用主題資料傳遞的Theme等等。而原生開發中的控件通常隻是指UI元素。
lib/main.dart 檔案入口
啟動項目
flutter run
hot reload 及時更新
- 指令行 r
- vscode 有調試工具,檔案記得儲存就行了
父級元件
- StatelessWidget 無狀态widget,類似靜态頁面,不與使用者互動
- StatefulWidget 有狀态widget,可以改變,可以與使用者互動
常用基礎widget
- Text:該 widget 可讓您建立一個帶格式的文本。
- Row、 Column: 這些具有彈性空間的布局類Widget可讓您在水準(Row)和垂直(Column)方向上建立靈活的布局。其設計是基于web開發中的Flexbox布局模型。
- Stack: 取代線性布局 (譯者語:和Android中的FrameLayout相似),Stack允許子 widget 堆疊, 你可以使用 Positioned 來定位他們相對于Stack的上下左右四條邊的位置。Stacks是基于Web開發中的絕對定位(absolute positioning )布局模型設計的。
- Container: Container 可讓您建立矩形視覺元素。container 可以裝飾一個BoxDecoration, 如 background、一個邊框、或者一個陰影。 Container 也可以具有邊距(margins)、填充(padding)和應用于其大小的限制(constraints)。另外, Container可以使用矩陣在三維空間中對其進行變換。
- Image 顯示圖檔,可以加載本地資源、file、網絡圖檔、記憶體圖檔
- TextField 輸入框,類似于EditText
詳解
Text
- 繼承關系
Object > Diagnosticable > DiagnosticableTree > Widget > StatelessWidget > Text
建立Text
- new Text() 構造方法建立,隻能生成一種style
- Text.rich() 靜态方法建立,能夠生成多種style
- new RichText() 與Text.rich()一樣
在編輯器vscode上 widget Text ctrl+左擊,都可以看見如下定義
Text()
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,
}) : assert(
data != null,
'A non-null String must be provided to a Text widget.',
),
textSpan = null,
super(key: key);
/// Creates a text widget with a [TextSpan].
///
/// The [textSpan] parameter must not be null.
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,
}) : assert(
textSpan != null,
'A non-null TextSpan must be provided to a Text.rich widget.',
),
data = null,
super(key: key);
常用Text屬性案例
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Welcome to Flutter',
home: new Scaffold(
appBar: new AppBar(
title: new Text('Welcome to Flutter'),
),
body: new Column(
children: <Widget>[
Text(
"隻不過是一隻腳放到另一隻腳前面。但我一直很驚訝這些原本是本能的事實際做起來有多困難。" * 20,
textAlign: TextAlign.end,
maxLines: 6, //最大行數
textScaleFactor: 2,//文本字型的縮放倍數,
style: new TextStyle(
decorationColor: const Color(0xffffffff), //線的顔色
decoration: TextDecoration.underline, //none無文字裝飾 lineThrough删除線 overline文字上面顯示線 underline文字下面顯示線
decorationStyle: TextDecorationStyle.solid, //文字裝飾的風格 dashed,dotted虛線(簡短間隔大小區分) double三條線 solid兩條線
wordSpacing: 1.0, //單詞間隙(負值可以讓單詞更緊湊)
letterSpacing: 1.0, //字母間隙(負值可以讓字母更緊湊)
fontStyle: FontStyle.italic, //文字樣式,斜體和正常
fontSize: 14.0, //字型大小
fontWeight: FontWeight.w900, //字型粗細 粗體和正常
color: Colors.red, //文字顔色
),
),
],
)),
);
}
}
TextSpan
TextSpan跟Text的差別就在于TextSpan是分片,我們可以把一串字元串分為幾個片段來管理,每個片段可以單獨設定樣式。
class TextSpan extends DiagnosticableTree {
/// Creates a [TextSpan] with the given values.
///
/// For the object to be useful, at least one of [text] or
/// [children] should be set.
const TextSpan({
this.style,
this.text,
this.children,
this.recognizer,
this.semanticsLabel,
});
其中style 跟上面的Text的style一緻,用來設定樣式,text就是要顯示的文本内容。 children是一個TextSpan的數組,不能為空,recognizer是用來處理手勢的
Text.rich(
TextSpan(
children:[
TextSpan(
text: "網址",
style: TextStyle(
color: Colors.black,
fontSize: 24,
)
),
TextSpan(
text: 'www.baidu.com',
style:TextStyle(
color: Colors.blue,
fontSize: 20,
fontStyle: FontStyle.italic,
)
)
]
)
)
案例總結
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Welcome to Flutter',
home: new Scaffold(
appBar: new AppBar(
title: new Text('Welcome to Flutter'),
),
body: new Column(
children: <Widget>[
Text(
"隻不過是一隻腳放到另一隻腳前面。但我一直很驚訝這些原本是本能的事實際做起來有多困難。" * 20,
textAlign: TextAlign.end,
maxLines: 6, //最大行數
textScaleFactor: 2,//文本字型的縮放倍數,
style: new TextStyle(
decorationColor: const Color(0xffffffff), //線的顔色
decoration: TextDecoration.underline, //none無文字裝飾 lineThrough删除線 overline文字上面顯示線 underline文字下面顯示線
decorationStyle: TextDecorationStyle.solid, //文字裝飾的風格 dashed,dotted虛線(簡短間隔大小區分) double三條線 solid兩條線
wordSpacing: 1.0, //單詞間隙(負值可以讓單詞更緊湊)
letterSpacing: 1.0, //字母間隙(負值可以讓字母更緊湊)
fontStyle: FontStyle.italic, //文字樣式,斜體和正常
fontSize: 14.0, //字型大小
fontWeight: FontWeight.w900, //字型粗細 粗體和正常
color: Colors.red, //文字顔色
),
),
Text.rich(
TextSpan(
children:[
TextSpan(
text: "網址",
style: TextStyle(
color: Colors.black,
fontSize: 24,
)
),
TextSpan(
text: 'www.baidu.com',
style:TextStyle(
color: Colors.blue,
fontSize: 20,
fontStyle: FontStyle.italic,
)
)
]
)
)
],
)),
);
}
}