這是我參與更文挑戰的第25天,活動詳情查看: 更文挑戰html
前面咱們聊了 Flutter 中 Text 各類屬性樣式調配的展現效果,這篇咱們稍微深刻一點,看看 Text 的源碼以及富文本的使用,最後聊聊選擇文本的應用。git
查看富文本以前,咱們先看看上篇的 Text
源碼,其實在上上篇咱們演示行高參數的時候就能夠看到雖然咱們使用的是 Text
,可是渲染時在 Widget 樹中看到的是 RichText
。
github
出現上述的緣由是什麼呢?咱們來瞅瞅源碼吧
首先 Text
繼承自 StatelessWidget
,下面咱們就直接看 build
方法便可。api
這裏看到上面註釋圈起來的部分,說 RichText 能夠更好的讓咱們控制文字樣式markdown
上面👆🏻能夠看出 build 方法最終返回的是 result
(550 行),而 result
建立的就是 RichText
對象,通常咱們沒有給文字添加語義標籤 semanticsLabel
,因此就會直接返回 RichText
Widget 了。less
如今咱們就知道爲啥咱們寫的是 Text ,但實際是 RichText 的 Widget 的緣由了ide
上面咱們知道了緣由,下面咱們就從一個簡單的富文原本走進 RichText
吧
👆🏻上面的效果,若是單獨使用 Text
寫是否是咱們要外部嵌套一個 Row+3個Text
, 咱們還要考慮換行問題,這樣就比較麻煩了,若是咱們使用 RichText
,就不須要考慮這麼多,關心樣式便可。oop
RichText(
text: TextSpan(
text: 'Flutter Widgets 已有 ',
children: [
TextSpan(
text: '25',
// 設置個性化覆蓋樣式
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
// 複用上層通用樣式
TextSpan(text: ' 系列文章'),
],
// 設置通用樣式
style: TextStyle(
color: Colors.blue,
),
),
)
複製代碼
這裏咱們主要關心樣式的設置,有 2
個點須要注意:post
上面咱們使用到了 TextSpan
,來一塊兒看看他的屬性吧。ui
這裏咱們看到 TextSpan
繼承自 InlineSpan
,實現了 HitTestTarget
(命中檢測)和 MouseTrackerAnnotation
(鼠標追蹤),屬性上也很是的簡單,經常使用的可能就是前 4 個,而後前 3 個咱們都瞭解使用過了,下面來看看第四個吧。
我如今把 25 這個數字變成紅色,而且要加上點擊事件怎麼辦呢?這時候就用到了第 4 個屬性 recognizer
。
// 點擊手勢檢測器
late TapGestureRecognizer tapRecognizer;
@override
void initState() {
tapRecognizer = TapGestureRecognizer()..onTap = _handleTap;
super.initState();
}
/// 處理點擊
void _handleTap() {
// 打印
print('tapRecognizer 25');
// 設置震動效果
HapticFeedback.vibrate();
}
// 這裏只貼圖 25 的部分代碼
TextSpan(
text: '25',
// 設置個性化覆蓋樣式
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.red,
),
// 設置點擊檢測器
recognizer: tapRecognizer,
)
複製代碼
這樣咱們再作,好比用戶協議與隱私政策的時候就能夠用到啦,能夠作單獨的樣式和跳轉。
上面咱們還只是說了富文本中文字多樣式的狀況,還有嵌套各類圖片的狀況,在實際富文本應用時比這個要複雜的多,文章中示例作核心的解法,具體還須要實際應用和創新。
若是在上面的基礎上咱們須要加上圖標怎麼處理呢?看看下面的代碼
RichText(
text: TextSpan(
children: [
// Flutter Logo
WidgetSpan(child: FlutterLogo()),
TextSpan(text: 'Flutter Widgets 已有 '),
TextSpan(
text: '25',
// 設置個性化覆蓋樣式
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.red,
),
recognizer: tapRecognizer,
),
// 連接圖標
WidgetSpan(
child: Icon(
Icons.link,
size: 16,
color: Colors.blue,
),
),
// 複用上層通用樣式
TextSpan(text: ' 系列文章'),
// 複製圖標
WidgetSpan(
child: Icon(
Icons.copy,
size: 16,
color: Colors.grey,
),
),
],
// 設置通用樣式
style: TextStyle(
color: Colors.blue,
),
),
)
複製代碼
這裏只是演示,實際項目中會根據下發的文本協議來解析,而後生成對應的 Widget 組合
另一種建立富文本的方式就是使用 Text.rich
,下面來一塊兒看看代碼吧
Text.rich(
TextSpan(
children: [
WidgetSpan(child: FlutterLogo()),
TextSpan(text: 'Flutter Widgets 已有 '),
TextSpan(
text: '25',
// 設置個性化覆蓋樣式
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.red,
),
recognizer: tapRecognizer,
),
WidgetSpan(
child: Icon(
Icons.link,
size: 16,
color: Colors.blue,
),
),
// 複用上層通用樣式
TextSpan(text: ' 系列文章'),
WidgetSpan(
child: Icon(
Icons.copy,
size: 16,
color: Colors.grey,
),
),
],
// 設置通用樣式
style: TextStyle(
color: Colors.blue,
),
),
)
複製代碼
到這裏 RichText
基本就聊完了,基礎的樣式咱們在前 2 篇文章已經聊過,能夠在專欄中回看。
上面展現的文本都是沒法選擇複製的,在實際項目中,有些內容文字是須要支持用戶能夠選擇複製的,這時咱們就須要將 Text
改變成 SelectableText
SelectableText(
"Text - ZeroFlutter",
style: TextStyle(
// 顏色藍色
color: Colors.blue,
// 字號 24
fontSize: 24,
),
)
複製代碼
在實際使用時,你會發現沒法指定溢出樣式了,默認就是直接剪裁掉了。
由於考慮到,複製確定是對全部文本進行操做,若是咱們溢出樣式是... 那麼複製出來就是展現的樣式,確定不符合需求。
因此在實際項目中,若是是長按複製所有可使用 Text
,選擇複製能夠 SelectableText
。
與 Text.rich
一致,要使用富文本時,能夠直接使用 SelectableText.rich
。
可是這裏有個顯示就是咱們不能使用
WidgetSpan
了,只能使用TextSpan
SelectableText.rich(
TextSpan(
children: [
// WidgetSpan(child: FlutterLogo()),
TextSpan(text: 'Flutter Widgets 已有 '),
TextSpan(
text: '25',
// 設置個性化覆蓋樣式
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.red,
),
recognizer: tapRecognizer,
),
// WidgetSpan(
// child: Icon(
// Icons.link,
// size: 16,
// color: Colors.blue,
// ),
// ),
// 複用上層通用樣式
TextSpan(text: ' 系列文章'),
// WidgetSpan(
// child: Icon(
// Icons.copy,
// size: 16,
// color: Colors.grey,
// ),
// ),
],
// 設置通用樣式
style: TextStyle(
color: Colors.blue,
),
),
)
複製代碼
基於 Flutter 🔥 最新版本
👏 歡迎點贊➕收藏➕關注,有任何問題隨時在下面👇評論,我會第一時間回覆哦