## 文本及樣式
### Text
Text用于顯示簡單樣式文本,它包含一些控制文本顯示樣式的一些屬性,一個簡單的例子如下:
```
Text("Hello world",
textAlign: TextAlign.center,
);
Text("Hello world! I'm Jack. "*4,
maxLines: 1,
overflow: TextOverflow.ellipsis,
);
Text("Hello world",
textScaleFactor: 1.5,
);
```
運行效果如下:

- `textAlign`:文本的對齊方式;可以選擇左對齊、右對齊還是居中。注意,對齊的參考系是Text widget本身。本例中雖然是指定了居中對齊,但因為Text文本內容寬度不足一行,Text的寬度和文本內容長度相等,那么這時指定對齊方式是沒有意義的,只有Text寬度大于文本內容長度時指定此屬性才有意義。下面我們指定一個較長的字符串:
```
Text("Hello world "*6, //字符串重復六次
textAlign: TextAlign.center,
);
```
運行效果如下:

字符串內容超過一行,Text寬度等于屏幕寬度,第二行文本便會居中顯示。
- `maxLines`、`overflow`:指定文本顯示的最大行數,默認情況下,文本是自動折行的,如果指定此參數,則文本最多不會超過指定的行。如果有多余的文本,可以通過`overflow`來指定截斷方式,默認是直接截斷,本例中指定的截斷方式`TextOverflow.ellipsis`,它會將多余文本截斷后以省略符“...”表示;TextOverflow的其它截斷方式請參考SDK文檔。
- `textScaleFactor`:代表文本相對于當前字體大小的縮放因子,相對于去設置文本的樣式`style`屬性的`fontSize`,它是調整字體大小的一個快捷方式。該屬性的默認值可以通過`MediaQueryData.textScaleFactor`獲得,如果沒有`MediaQuery`,那么會默認值將為1.0。
### TextStyle
TextStyle用于指定文本顯示的樣式如顏色、字體、粗細、背景等。我們看一個示例:
```
Text("Hello world",
style: TextStyle(
color: Colors.blue,
fontSize: 18.0,
height: 1.2,
fontFamily: "Courier",
background: new Paint()..color=Colors.yellow,
decoration:TextDecoration.underline,
decorationStyle: TextDecorationStyle.dashed
),
);
```
效果如下:

此示例只展示了TextStyle的部分屬性,它還有一些其它屬性,屬性名基本都是自解釋的,在此不再贅述,讀者可以查閱SDK文檔。值得注意的是:
- `height`:該屬性用于指定行高,但它并不是一個絕對值,而是一個因子,具體的行高等于`fontSize`\*`height`。
- `fontFamily` :由于不同平臺默認支持的字體集不同,所以在手動指定字體時一定要先在不同平臺測試一下。
- `fontSize`:該屬性和Text的`textScaleFactor`都用于控制字體大小。但是有兩給主要區別:
- `fontSize`可以精確指定字體大小,而`textScaleFactor`只能通過縮放比例來控制。
- `textScaleFactor`主要是用于系統字體大小設置改變時對Flutter應用字體進行全局調整,而`fontSize`通常用于單個文本。
### TextSpan
在上面的例子中,Text的所有文本內容只能按同一種樣式,如果我們需要對一個Text內容的不同部分按照不同的樣式顯示,這時就可以使用`TextSpan`,它代表文本的一個“片段”。我們看看TextSpan的定義:
```
const TextSpan({
TextStyle style,
Sting text,
List<TextSpan> children,
GestureRecognizer recognizer,
});
```
其中`style` 和 `text`屬性代表該文本片段的樣式和內容。 `children`是一個`TextSpan`的數組,也就是說`TextSpan`可以包括其他`TextSpan`。而`recognizer`用于對該文本片段上用于手勢進行識別處理。下面我們看一個效果,然后用`TextSpan`實現它。

源碼:
```
Text.rich(TextSpan(
children: [
TextSpan(
text: "Home: "
),
TextSpan(
text: "https://flutterchina.club",
style: TextStyle(
color: Colors.blue
),
recognizer: _tapRecognizer
),
]
))
```
- 上面代碼中,我們通過TextSpan實現了一個基礎文本片段和一個鏈接片段,然后通過`Text.rich` 方法將`TextSpan` 添加到Text中,之所以可以這樣做,是因為Text其實就是RichText的一個包裝,而RichText是可以顯示多種樣式(富文本)的widget。
- `_tapRecognizer`,它是點擊鏈接后的一個處理器(代碼已省略),關于手勢識別的更多內容我們將在后面單獨介紹。
### DefaultTextStyle
在widget樹中,文本的樣式默認是可以被繼承的,因此,如果在widget樹的某一個節點處設置一個默認的文本樣式,那么該節點的子樹中所有文本都會默認使用這個樣式,而DefaultTextStyle正是用于設置默認文本樣式的。下面我們看一個例子:
```
DefaultTextStyle(
//1.設置文本默認樣式
style: TextStyle(
color:Colors.red,
fontSize: 20.0,
),
textAlign: TextAlign.start,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("hello world"),
Text("I am Jack"),
Text("I am Jack",
style: TextStyle(
inherit: false, //2.不繼承默認樣式
color: Colors.grey
),
),
],
),
);
```
上面代碼中,我們首先設置了一個默認的文本樣式,即字體為20像素(邏輯像素)、顏色為紅色。然后通過`DefaultTextStyle` 設置給了子樹Column節點處,這樣一來Column的所有子孫Text默認都會繼承該樣式,除非Text顯示指定不繼承樣式,如代碼中注釋2。示例運行效果如下:

### 使用字體
可以在Flutter應用程序中使用不同的字體。例如,我們可能會使用設計人員創建的自定義字體,或者其它第三方的字體,如[Google Fonts](https://fonts.google.com/)中的字體。本節將介紹如何為Flutter應用配置字體,并在渲染文本時使用它們。
在Flutter中使用字體分兩步完成。首先在`pubspec.yaml`中聲明它們,以確保它們會打包到應用程序中。然后通過[`TextStyle`](https://docs.flutter.io/flutter/painting/TextStyle-class.html)屬性使用字體。
#### 在asset中聲明
要將字體打文件打包到應用中,和使用其它資源一樣,要先在`pubspec.yaml`中聲明它。然后將字體文件復制到在`pubspec.yaml`中指定的位置。如:
```
flutter:
fonts:
- family: Raleway
fonts:
- asset: assets/fonts/Raleway-Regular.ttf
- asset: assets/fonts/Raleway-Medium.ttf
weight: 500
- asset: assets/fonts/Raleway-SemiBold.ttf
weight: 600
- family: AbrilFatface
fonts:
- asset: assets/fonts/abrilfatface/AbrilFatface-Regular.ttf
```
#### 使用字體
```
// 聲明文本樣式
const textStyle = const TextStyle(
fontFamily: 'Raleway',
);
// 使用文本樣式
var buttonText = const Text(
"Use the font for this text",
style: textStyle,
);
```
#### Package中的字體
要使用Package中定義的字體,必須提供`package`參數。例如,假設上面的字體聲明位于`my_package`包中。然后創建TextStyle的過程如下:
```
const textStyle = const TextStyle(
fontFamily: 'Raleway',
package: 'my_package', //指定包名
);
```
如果在package包內部使用它自己定義的字體,也應該在創建文本樣式時指定`package`參數,如上例所示。
一個包也可以只提供字體文件而不需要在pubspec.yaml中聲明。 這些文件應該存放在包的`lib/`文件夾中。字體文件不會自動綁定到應用程序中,應用程序可以在聲明字體時有選擇地使用這些字體。假設一個名為my\_package的包中有一個字體文件:
```
lib/fonts/Raleway-Medium.ttf
```
然后,應用程序可以聲明一個字體,如下面的示例所示:
```
flutter:
fonts:
- family: Raleway
fonts:
- asset: assets/fonts/Raleway-Regular.ttf
- asset: packages/my_package/fonts/Raleway-Medium.ttf
weight: 500
```
`lib/`是隱含的,所以它不應該包含在asset路徑中。
在這種情況下,由于應用程序本地定義了字體,所以在創建TextStyle時可以不指定`package`參數:
```
const textStyle = const TextStyle(
fontFamily: 'Raleway',
);
```
- 緣起
- 起步
- 移動開發技術簡介
- Flutter簡介
- 搭建Flutter開發環境
- 常見配置問題
- Dart語言簡介
- 第一個Flutter應用
- 計數器示例
- 路由管理
- 包管理
- 資源管理
- 調試Flutter APP
- Dart線程模型及異常捕獲
- 基礎Widgets
- Widget簡介
- 文本、字體樣式
- 按鈕
- 圖片和Icon
- 單選框和復選框
- 輸入框和表單
- 布局類Widgets
- 布局類Widgets簡介
- 線性布局Row、Column
- 彈性布局Flex
- 流式布局Wrap、Flow
- 層疊布局Stack、Positioned
- 容器類Widgets
- Padding
- 布局限制類容器ConstrainedBox、SizeBox
- 裝飾容器DecoratedBox
- 變換Transform
- Container容器
- Scaffold、TabBar、底部導航
- 可滾動Widgets
- 可滾動Widgets簡介
- SingleChildScrollView
- ListView
- GridView
- CustomScrollView
- 滾動監聽及控制ScrollController
- 功能型Widgets
- 導航返回攔截-WillPopScope
- 數據共享-InheritedWidget
- 主題-Theme
- 事件處理與通知
- 原始指針事件處理
- 手勢識別
- 全局事件總線
- 通知Notification
- 動畫
- Flutter動畫簡介
- 動畫結構
- 自定義路由過渡動畫
- Hero動畫
- 交錯動畫
- 自定義Widget
- 自定義Widget方法簡介
- 通過組合現有Widget實現
- 實例:TurnBox
- CustomPaint與Canvas
- 實例:圓形漸變進度條(自繪)
- 文件操作與網絡請求
- 文件操作
- Http請求-HttpClient
- Http請求-Dio package
- 實例:Http分塊下載
- WebSocket
- 使用Socket API
- Json轉Model
- 包與插件
- 開發package
- 插件開發:平臺通道簡介
- 插件開發:實現Android端API
- 插件開發:實現IOS端API
- 系統能力調用
- 國際化
- 讓App支持多語言
- 實現Localizations
- 使用Intl包
- Flutter核心原理
- Flutter UI系統
- Element和BuildContext
- RenderObject與RenderBox
- Flutter從啟動到顯示